1 /* Clearlooks - a cairo based GTK+ engine
2 * Copyright (C) 2006 Richard Stellingwerff <remenic@gmail.com>
3 * Copyright (C) 2006 Daniel Borgman <daniel.borgmann@gmail.com>
4 * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>
5 * Copyright (C) 2007-2008 Andrea Cimitan <andrea.cimitan@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * Project contact: <gnome-themes-list@gnome.org>
22 *
23 */
24
25
26 #include "clearlooks_draw.h"
27 #include "clearlooks_style.h"
28 #include "clearlooks_types.h"
29
30 #include "support.h"
31 #include <ge-support.h>
32 #include <math.h>
33
34 #include <cairo.h>
35
36 /* Normal shadings */
37 #define SHADE_TOP 1.055
38 #define SHADE_CENTER_TOP 1.01
39 #define SHADE_CENTER_BOTTOM 0.98
40 #define SHADE_BOTTOM 0.90
41
42 typedef void (*menubar_draw_proto) (cairo_t *cr,
43 const ClearlooksColors *colors,
44 const WidgetParameters *params,
45 const MenuBarParameters *menubar,
46 int x, int y, int width, int height);
47
48 static void
clearlooks_draw_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double width,double height,double radius,uint8 corners)49 clearlooks_draw_inset (cairo_t *cr,
50 const CairoColor *bg_color,
51 double x, double y, double width, double height,
52 double radius, uint8 corners)
53 {
54 CairoColor shadow;
55 CairoColor highlight;
56 double line_width;
57 double min = MIN (width, height);
58
59 line_width = cairo_get_line_width (cr);
60
61 /* not really sure of shading ratios... we will think */
62 ge_shade_color (bg_color, 0.94, &shadow);
63 ge_shade_color (bg_color, 1.06, &highlight);
64
65 /* highlight */
66 cairo_save (cr);
67
68 cairo_move_to (cr, x, y + height);
69 cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
70 cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
71 cairo_line_to (cr, x + width, y);
72 cairo_line_to (cr, x, y);
73 cairo_close_path (cr);
74
75 cairo_clip (cr);
76
77 ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
78 width - line_width, height - line_width,
79 radius, corners);
80
81 ge_cairo_set_color (cr, &shadow);
82 cairo_stroke (cr);
83
84 cairo_restore (cr);
85
86 /* shadow */
87 cairo_save (cr);
88
89 cairo_move_to (cr, x, y + height);
90 cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
91 cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
92 cairo_line_to (cr, x + width, y);
93 cairo_line_to (cr, x + width, y + height);
94 cairo_close_path (cr);
95
96 cairo_clip (cr);
97
98 ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
99 width - line_width, height - line_width,
100 radius, corners);
101
102 ge_cairo_set_color (cr, &highlight);
103 cairo_stroke (cr);
104
105 cairo_restore (cr);
106 }
107
108 static void
clearlooks_draw_shadow(cairo_t * cr,const ClearlooksColors * colors,gfloat radius,int width,int height)109 clearlooks_draw_shadow (cairo_t *cr, const ClearlooksColors *colors, gfloat radius, int width, int height)
110 {
111 CairoColor shadow;
112 cairo_save (cr);
113
114 ge_shade_color (&colors->shade[6], 0.92, &shadow);
115
116 cairo_set_line_width (cr, 1.0);
117 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
118
119 cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1);
120
121 cairo_move_to (cr, width - 0.5, radius);
122 ge_cairo_rounded_corner (cr, width - 0.5, height - 0.5, radius, CR_CORNER_BOTTOMRIGHT);
123 cairo_line_to (cr, radius, height - 0.5);
124
125 cairo_stroke (cr);
126 cairo_restore (cr);
127 }
128
129 /* This is copied at least in clearlooks_draw_gummy.c.
130 * KEEP IN SYNC IF POSSIBLE! */
131 static void
clearlooks_draw_top_left_highlight(cairo_t * cr,const CairoColor * color,const WidgetParameters * params,int x,int y,int width,int height,gdouble radius,CairoCorners corners)132 clearlooks_draw_top_left_highlight (cairo_t *cr, const CairoColor *color,
133 const WidgetParameters *params,
134 int x, int y, int width, int height,
135 gdouble radius, CairoCorners corners)
136 {
137 CairoColor hilight;
138
139 double line_width = cairo_get_line_width (cr);
140 double offset = line_width / 2.0;
141 double light_top, light_bottom, light_left, light_right;
142
143 cairo_save (cr);
144
145 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
146
147 light_top = y + offset;
148 light_bottom = y + height;
149 light_left = x + offset;
150 light_right = x + width;
151
152 if (corners & CR_CORNER_BOTTOMLEFT)
153 light_bottom -= radius;
154 if (corners & CR_CORNER_TOPRIGHT)
155 light_right -= radius;
156
157 ge_shade_color (color, params->style_constants->topleft_highlight_shade, &hilight);
158 cairo_move_to (cr, light_left, light_bottom);
159
160 ge_cairo_rounded_corner (cr, light_left, light_top, radius, corners & CR_CORNER_TOPLEFT);
161
162 cairo_line_to (cr, light_right, light_top);
163 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, params->style_constants->topleft_highlight_alpha);
164 cairo_stroke (cr);
165
166 cairo_restore (cr);
167 }
168
169 #ifdef DEVELOPMENT
170 #warning seems to be very slow in scrollbar_stepper
171 #endif
172
173 static void
clearlooks_draw_highlight_and_shade(cairo_t * cr,const ClearlooksColors * colors,const ShadowParameters * params,int width,int height,gdouble radius)174 clearlooks_draw_highlight_and_shade (cairo_t *cr, const ClearlooksColors *colors,
175 const ShadowParameters *params,
176 int width, int height, gdouble radius)
177 {
178 CairoColor hilight;
179 CairoColor shadow;
180 uint8 corners = params->corners;
181 double x = 1.0;
182 double y = 1.0;
183
184 ge_shade_color (&colors->bg[0], 1.06, &hilight);
185 ge_shade_color (&colors->bg[0], 0.94, &shadow);
186
187 width -= 2;
188 height -= 2;
189
190 cairo_save (cr);
191
192 /* Top/Left highlight */
193 if (corners & CR_CORNER_BOTTOMLEFT)
194 cairo_move_to (cr, x + 0.5, y+height-radius);
195 else
196 cairo_move_to (cr, x + 0.5, y+height);
197
198 ge_cairo_rounded_corner (cr, x + 0.5, y + 0.5, radius, corners & CR_CORNER_TOPLEFT);
199
200 if (corners & CR_CORNER_TOPRIGHT)
201 cairo_line_to (cr, x+width-radius, y + 0.5);
202 else
203 cairo_line_to (cr, x+width, y + 0.5);
204
205 if (params->shadow & CL_SHADOW_OUT)
206 ge_cairo_set_color (cr, &hilight);
207 else
208 ge_cairo_set_color (cr, &shadow);
209
210 cairo_stroke (cr);
211
212 /* Bottom/Right highlight -- this includes the corners */
213 cairo_arc (cr, x + width - 0.5 - radius, y + radius, radius, G_PI * (3/2.0+1/4.0), G_PI * 2);
214 ge_cairo_rounded_corner (cr, x+width - 0.5, y+height - 0.5, radius, corners & CR_CORNER_BOTTOMRIGHT);
215 cairo_arc (cr, x + radius, y + height - 0.5 - radius, radius, G_PI * 1/2, G_PI * 3/4);
216
217 if (params->shadow & CL_SHADOW_OUT)
218 ge_cairo_set_color (cr, &shadow);
219 else
220 ge_cairo_set_color (cr, &hilight);
221
222 cairo_stroke (cr);
223
224 cairo_restore (cr);
225 }
226
227 static void
clearlooks_set_border_gradient(cairo_t * cr,const CairoColor * color,double hilight,int width,int height)228 clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height)
229 {
230 cairo_pattern_t *pattern;
231
232 CairoColor bottom_shade;
233 ge_shade_color (color, hilight, &bottom_shade);
234
235 pattern = cairo_pattern_create_linear (0, 0, width, height);
236 cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b);
237 cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b);
238
239 cairo_set_source (cr, pattern);
240 cairo_pattern_destroy (pattern);
241 }
242
243 static void
clearlooks_draw_gripdots(cairo_t * cr,const ClearlooksColors * colors,int x,int y,int width,int height,int xr,int yr,float contrast)244 clearlooks_draw_gripdots (cairo_t *cr, const ClearlooksColors *colors, int x, int y,
245 int width, int height, int xr, int yr,
246 float contrast)
247 {
248 const CairoColor *dark = &colors->shade[4];
249 CairoColor hilight;
250 int i, j;
251 int xoff, yoff;
252 int x_start, y_start;
253
254 ge_shade_color (dark, 1.5, &hilight);
255
256 /* The "- 1" is because there is no space in front of the first dot. */
257 x_start = x + width / 2 - ((xr * 3 - 1) / 2);
258 y_start = y + height / 2 - ((yr * 3 - 1) / 2);
259
260 for ( i = 0; i < xr; i++ )
261 {
262 for ( j = 0; j < yr; j++ )
263 {
264 xoff = 3 * i;
265 yoff = 3 * j;
266
267 cairo_rectangle (cr, x_start + xoff, y_start + yoff, 2, 2);
268 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8+contrast);
269 cairo_fill (cr);
270 cairo_rectangle (cr, x_start + xoff, y_start + yoff, 1, 1);
271 cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.8+contrast);
272 cairo_fill (cr);
273 }
274 }
275 }
276
277 static void
clearlooks_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)278 clearlooks_draw_button (cairo_t *cr,
279 const ClearlooksColors *colors,
280 const WidgetParameters *params,
281 int x, int y, int width, int height)
282 {
283 double xoffset = 0, yoffset = 0;
284 double radius = params->radius;
285 const CairoColor *fill = &colors->bg[params->state_type];
286 CairoColor border_normal = colors->shade[6];
287 CairoColor border_disabled = colors->shade[4];
288
289 CairoColor shadow;
290 ge_shade_color (&border_normal, 1.04, &border_normal);
291 ge_shade_color (&border_normal, 0.94, &shadow);
292 ge_shade_color (&border_disabled, 1.08, &border_disabled);
293
294 cairo_save (cr);
295
296 cairo_translate (cr, x, y);
297 cairo_set_line_width (cr, 1.0);
298
299 if (params->xthickness >= 3 && params->ythickness >= 3)
300 {
301 xoffset = 1;
302 yoffset = 1;
303 }
304
305 radius = MIN (radius, MIN ((width - 2.0 - xoffset * 2.0) / 2.0, (height - 2.0 - yoffset * 2) / 2.0));
306
307 if (params->xthickness >= 3 && params->ythickness >= 3)
308 {
309 params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners);
310 }
311
312 ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1,
313 width-(xoffset*2)-2,
314 height-(yoffset*2)-2,
315 radius, params->corners);
316
317 if (!params->active)
318 {
319 cairo_pattern_t *pattern;
320 CairoColor top_shade, topmiddle_shade, bottom_shade, middle_shade;
321
322 ge_shade_color (fill, SHADE_TOP, &top_shade);
323 ge_shade_color (fill, SHADE_CENTER_TOP, &topmiddle_shade);
324 ge_shade_color (fill, SHADE_CENTER_BOTTOM, &middle_shade);
325 ge_shade_color (fill, SHADE_BOTTOM, &bottom_shade);
326
327 cairo_save (cr);
328 cairo_clip_preserve (cr);
329
330 pattern = cairo_pattern_create_linear (0, 0, 0, height);
331 cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b);
332 cairo_pattern_add_color_stop_rgb (pattern, 0.3, topmiddle_shade.r, topmiddle_shade.g, topmiddle_shade.b);
333 cairo_pattern_add_color_stop_rgb (pattern, 0.7, middle_shade.r, middle_shade.g, middle_shade.b);
334 cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b);
335 cairo_set_source (cr, pattern);
336 cairo_fill (cr);
337 cairo_pattern_destroy (pattern);
338
339 cairo_move_to (cr, width-(xoffset*2)-0.5, 0);
340 cairo_line_to (cr, width-(xoffset*2)-0.5, height);
341 ge_cairo_set_color (cr, &bottom_shade);
342 cairo_stroke (cr);
343
344 /* Draw topleft shadow */
345 params->style_functions->draw_top_left_highlight (cr, fill, params, xoffset + 1, yoffset + 1,
346 width - 2*(xoffset + 1), height - 2*(yoffset + 1),
347 MAX(radius-1, 0), params->corners);
348
349 cairo_restore (cr);
350 }
351 else
352 {
353 cairo_pattern_t *pattern;
354
355 ge_cairo_set_color (cr, fill);
356 cairo_fill_preserve (cr);
357
358 pattern = cairo_pattern_create_linear (0, 0, 0, height);
359 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0);
360 cairo_pattern_add_color_stop_rgba (pattern, 0.4, shadow.r, shadow.g, shadow.b, 0.0);
361 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.2);
362 cairo_set_source (cr, pattern);
363 cairo_fill_preserve (cr);
364 cairo_pattern_destroy (pattern);
365
366 pattern = cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset);
367 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32);
368 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
369 cairo_set_source (cr, pattern);
370 cairo_fill_preserve (cr);
371 cairo_pattern_destroy (pattern);
372
373 pattern = cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0);
374 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32);
375 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
376 cairo_set_source (cr, pattern);
377 cairo_fill (cr);
378 cairo_pattern_destroy (pattern);
379 }
380
381 /* Drawing the border */
382 if (!params->active && params->is_default)
383 {
384 ge_shade_color (&border_normal, 0.74, &border_normal);
385 }
386
387 ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, params->corners);
388
389 if (params->disabled)
390 {
391 ge_cairo_set_color (cr, &border_disabled);
392 }
393 else
394 {
395 if (!params->active)
396 clearlooks_set_border_gradient (cr, &border_normal,
397 params->is_default ? 1.1 : 1.3, 0, height);
398 else
399 {
400 ge_shade_color (&border_normal, 1.08, &border_normal);
401 ge_cairo_set_color (cr, &border_normal);
402 }
403 }
404
405 cairo_stroke (cr);
406
407 cairo_restore (cr);
408 }
409
410 static void
clearlooks_draw_entry(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const FocusParameters * focus,int x,int y,int width,int height)411 clearlooks_draw_entry (cairo_t *cr,
412 const ClearlooksColors *colors,
413 const WidgetParameters *params,
414 const FocusParameters *focus,
415 int x, int y, int width, int height)
416 {
417 const CairoColor *base = &colors->base[params->state_type];
418 CairoColor border = colors->shade[params->disabled ? 3 : 6];
419 double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0));
420 int xoffset, yoffset;
421
422 if (params->focus)
423 border = focus->color;
424
425 cairo_save (cr);
426
427 cairo_translate (cr, x, y);
428 cairo_set_line_width (cr, 1.0);
429
430 if (params->xthickness >= 3 && params->ythickness >= 3)
431 {
432 params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners);
433 xoffset = 1;
434 yoffset = 1;
435 }
436 else
437 {
438 xoffset = 0;
439 yoffset = 0;
440 }
441
442 /* Now fill the area we want to be base[NORMAL]. */
443 ge_cairo_rounded_rectangle (cr, xoffset + 1, yoffset + 1, width - (xoffset + 1)*2,
444 height - (yoffset + 1) * 2, MAX(0, radius-1),
445 params->corners);
446 ge_cairo_set_color (cr, base);
447 cairo_fill (cr);
448
449 /* Draw the inner shadow */
450 if (params->focus)
451 {
452 CairoColor focus_shadow;
453 ge_shade_color (&border, 1.61, &focus_shadow);
454
455 clearlooks_set_mixed_color (cr, base, &focus_shadow, 0.5);
456 ge_cairo_inner_rounded_rectangle (cr, xoffset + 1, yoffset + 1,
457 width - (xoffset + 1)*2, height - (yoffset + 1)*2,
458 MAX(0, radius-1), params->corners);
459 cairo_stroke (cr);
460 }
461 else
462 {
463 CairoColor shadow;
464 ge_shade_color (&border, 0.925, &shadow);
465
466 cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.05 : 0.1);
467
468 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
469 cairo_move_to (cr, 2.5, height-radius);
470 cairo_arc (cr, xoffset + 1.5 + MAX(0, radius-1), yoffset + 1.5 + MAX(0, radius-1),
471 MAX(0, radius-1), G_PI, 270*(G_PI/180));
472 cairo_line_to (cr, width-radius, 2.5);
473 cairo_stroke (cr);
474 }
475
476 ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset,
477 width-2*xoffset, height-2*yoffset,
478 radius, params->corners);
479 if (params->focus || params->disabled)
480 ge_cairo_set_color (cr, &border);
481 else
482 clearlooks_set_border_gradient (cr, &border, 1.32, 0, height);
483 cairo_stroke (cr);
484
485 cairo_restore (cr);
486 }
487
488 static void
clearlooks_draw_entry_progress(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const EntryProgressParameters * progress,int x,int y,int width,int height)489 clearlooks_draw_entry_progress (cairo_t *cr,
490 const ClearlooksColors *colors,
491 const WidgetParameters *params,
492 const EntryProgressParameters *progress,
493 int x, int y, int width, int height)
494 {
495 CairoColor border;
496 CairoColor fill;
497 gint entry_width, entry_height;
498 double entry_radius;
499 double radius;
500
501 cairo_save (cr);
502
503 fill = colors->bg[params->state_type];
504 ge_shade_color (&fill, 0.9, &border);
505
506 if (progress->max_size_known)
507 {
508 entry_width = progress->max_size.width + progress->border.left + progress->border.right;
509 entry_height = progress->max_size.height + progress->border.top + progress->border.bottom;
510 entry_radius = MIN (params->radius, MIN ((entry_width - 4.0) / 2.0, (entry_height - 4.0) / 2.0));
511 }
512 else
513 {
514 entry_radius = params->radius;
515 }
516
517 radius = MAX (0, entry_radius + 1.0 - MAX (MAX (progress->border.left, progress->border.right),
518 MAX (progress->border.top, progress->border.bottom)));
519
520 if (progress->max_size_known)
521 {
522 /* Clip to the max size, and then draw a (larger) rectangle ... */
523 ge_cairo_rounded_rectangle (cr, progress->max_size.x,
524 progress->max_size.y,
525 progress->max_size.width,
526 progress->max_size.height,
527 radius,
528 CR_CORNER_ALL);
529 cairo_clip (cr);
530
531 /* We just draw wider by one pixel ... */
532 ge_cairo_set_color (cr, &fill);
533 cairo_rectangle (cr, x, y + 1, width, height - 2);
534 cairo_fill (cr);
535
536 cairo_set_line_width (cr, 1.0);
537 ge_cairo_set_color (cr, &border);
538 ge_cairo_inner_rectangle (cr, x - 1, y, width + 2, height);
539 cairo_stroke (cr);
540 }
541 else
542 {
543 ge_cairo_rounded_rectangle (cr, x, y, width + 10, height + 10, radius, CR_CORNER_ALL);
544 cairo_clip (cr);
545 ge_cairo_rounded_rectangle (cr, x - 10, y - 10, width + 10, height + 10, radius, CR_CORNER_ALL);
546 cairo_clip (cr);
547
548 ge_cairo_set_color (cr, &fill);
549 ge_cairo_rounded_rectangle (cr, x + 1, y + 1, width - 2, height - 2, radius, CR_CORNER_ALL);
550 cairo_fill (cr);
551
552 cairo_set_line_width (cr, 1.0);
553 ge_cairo_set_color (cr, &border);
554 ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1.0, height - 1.0, radius, CR_CORNER_ALL);
555 cairo_stroke (cr);
556 }
557
558 cairo_restore (cr);
559 }
560
561 static void
clearlooks_draw_spinbutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)562 clearlooks_draw_spinbutton (cairo_t *cr,
563 const ClearlooksColors *colors,
564 const WidgetParameters *params,
565 int x, int y, int width, int height)
566 {
567 const CairoColor *border = &colors->shade[!params->disabled ? 5 : 3];
568 CairoColor hilight;
569
570 params->style_functions->draw_button (cr, colors, params, x, y, width, height);
571
572 ge_shade_color (&colors->bg[0], params->style_constants->topleft_highlight_shade, &hilight);
573 hilight.a = params->style_constants->topleft_highlight_alpha;
574
575 cairo_translate (cr, x, y);
576
577 cairo_move_to (cr, params->xthickness + 0.5, (height/2) + 0.5);
578 cairo_line_to (cr, width-params->xthickness - 0.5, (height/2) + 0.5);
579 ge_cairo_set_color (cr, border);
580 cairo_stroke (cr);
581
582 cairo_move_to (cr, params->xthickness + 0.5, (height/2)+1.5);
583 cairo_line_to (cr, width-params->xthickness - 0.5, (height/2)+1.5);
584 ge_cairo_set_color (cr, &hilight);
585 cairo_stroke (cr);
586 }
587
588 static void
clearlooks_draw_spinbutton_down(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)589 clearlooks_draw_spinbutton_down (cairo_t *cr,
590 const ClearlooksColors *colors,
591 const WidgetParameters *params,
592 int x, int y, int width, int height)
593 {
594 cairo_pattern_t *pattern;
595 double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0));
596 CairoColor shadow;
597 ge_shade_color (&colors->bg[0], 0.8, &shadow);
598
599 cairo_translate (cr, x+1, y+1);
600
601 ge_cairo_rounded_rectangle (cr, 1, 1, width-4, height-4, radius, params->corners);
602
603 ge_cairo_set_color (cr, &colors->bg[params->state_type]);
604
605 cairo_fill_preserve (cr);
606
607 pattern = cairo_pattern_create_linear (0, 0, 0, height);
608 cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b);
609 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
610
611 cairo_set_source (cr, pattern);
612 cairo_fill (cr);
613
614 cairo_pattern_destroy (pattern);
615 }
616
617 static void
clearlooks_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)618 clearlooks_scale_draw_gradient (cairo_t *cr,
619 const CairoColor *c1,
620 const CairoColor *c2,
621 const CairoColor *c3,
622 int x, int y, int width, int height,
623 boolean horizontal)
624 {
625 cairo_pattern_t *pattern;
626
627 pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 : width + 1, horizontal ? height + 1: 0.5);
628 cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b);
629 cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b);
630
631 cairo_rectangle (cr, x, y, width, height);
632 cairo_set_source (cr, pattern);
633 cairo_fill (cr);
634 cairo_pattern_destroy (pattern);
635
636 ge_cairo_set_color (cr, c3);
637 ge_cairo_inner_rectangle (cr, x, y, width, height);
638 cairo_stroke (cr);
639 }
640
641 #define TROUGH_SIZE 7
642 static void
clearlooks_draw_scale_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)643 clearlooks_draw_scale_trough (cairo_t *cr,
644 const ClearlooksColors *colors,
645 const WidgetParameters *params,
646 const SliderParameters *slider,
647 int x, int y, int width, int height)
648 {
649 int trough_width, trough_height;
650 double translate_x, translate_y;
651
652 cairo_save (cr);
653
654 if (slider->horizontal)
655 {
656 trough_width = width;
657 trough_height = TROUGH_SIZE;
658
659 translate_x = x;
660 translate_y = y + (height/2) - (TROUGH_SIZE/2);
661 }
662 else
663 {
664 trough_width = TROUGH_SIZE;
665 trough_height = height;
666
667 translate_x = x + (width/2) - (TROUGH_SIZE/2);
668 translate_y = y;
669 }
670
671 cairo_set_line_width (cr, 1.0);
672 cairo_translate (cr, translate_x, translate_y);
673
674 if (!slider->fill_level)
675 params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width, trough_height, 0, 0);
676
677 if (!slider->lower && !slider->fill_level)
678 {
679 CairoColor shadow;
680 ge_shade_color (&colors->shade[2], 0.96, &shadow);
681
682 clearlooks_scale_draw_gradient (cr, &shadow, /* top */
683 &colors->shade[2], /* bottom */
684 &colors->shade[4], /* border */
685 1.0, 1.0, trough_width - 2, trough_height - 2,
686 slider->horizontal);
687 }
688 else
689 {
690 CairoColor border = colors->spot[2];
691 border.a = 0.64;
692
693 clearlooks_scale_draw_gradient (cr, &colors->spot[1], /* top */
694 &colors->spot[0], /* bottom */
695 &border, /* border */
696 1.0, 1.0, trough_width - 2, trough_height - 2,
697 slider->horizontal);
698 }
699 cairo_restore (cr);
700 }
701
702 static void
clearlooks_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)703 clearlooks_draw_slider (cairo_t *cr,
704 const ClearlooksColors *colors,
705 const WidgetParameters *params,
706 int x, int y, int width, int height)
707 {
708 const CairoColor *spot = &colors->spot[1];
709 const CairoColor *fill = &colors->shade[2];
710 CairoColor border = colors->shade[params->disabled ? 4 : 6];
711 double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
712
713 cairo_pattern_t *pattern;
714
715 cairo_set_line_width (cr, 1.0);
716 cairo_translate (cr, x, y);
717
718 if (params->prelight)
719 border = colors->spot[2];
720
721 /* fill the widget */
722 ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-2, height-2, radius, params->corners);
723
724 /* Fake light */
725 if (!params->disabled)
726 {
727 const CairoColor *top = &colors->shade[0];
728 const CairoColor *bot = &colors->shade[2];
729
730 pattern = cairo_pattern_create_linear (0, 0, 0, height);
731 cairo_pattern_add_color_stop_rgb (pattern, 0.0, top->r, top->g, top->b);
732 cairo_pattern_add_color_stop_rgb (pattern, 1.0, bot->r, bot->g, bot->b);
733 cairo_set_source (cr, pattern);
734 cairo_fill (cr);
735 cairo_pattern_destroy (pattern);
736 }
737 else
738 {
739 ge_cairo_set_color (cr, fill);
740 cairo_fill (cr);
741 }
742
743 /* Set the clip */
744 cairo_save (cr);
745 cairo_rectangle (cr, 1.0, 1.0, 6, height-2);
746 cairo_rectangle (cr, width-7.0, 1.0, 6, height-2);
747 cairo_clip_preserve (cr);
748
749 cairo_new_path (cr);
750
751 /* Draw the handles */
752 ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-1, height-1, radius, params->corners);
753 pattern = cairo_pattern_create_linear (1.0, 1.0, 1.0, 1.0+height);
754
755 if (params->prelight)
756 {
757 CairoColor highlight;
758 ge_shade_color (spot, 1.3, &highlight);
759 cairo_pattern_add_color_stop_rgb (pattern, 0.0, highlight.r, highlight.g, highlight.b);
760 cairo_pattern_add_color_stop_rgb (pattern, 1.0, spot->r, spot->g, spot->b);
761 cairo_set_source (cr, pattern);
762 }
763 else
764 {
765 CairoColor hilight;
766 ge_shade_color (fill, 1.3, &hilight);
767 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
768 }
769
770 cairo_fill (cr);
771 cairo_pattern_destroy (pattern);
772
773 cairo_restore (cr);
774
775 /* Draw the border */
776 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
777
778 if (params->prelight || params->disabled)
779 ge_cairo_set_color (cr, &border);
780 else
781 clearlooks_set_border_gradient (cr, &border, 1.2, 0, height);
782 cairo_stroke (cr);
783
784 /* Draw handle lines */
785 if (width > 14)
786 {
787 cairo_move_to (cr, 6.5, 1.0);
788 cairo_line_to (cr, 6.5, height-1);
789
790 cairo_move_to (cr, width-6.5, 1.0);
791 cairo_line_to (cr, width-6.5, height-1);
792
793 cairo_set_line_width (cr, 1.0);
794 border.a = params->disabled ? 0.6 : 0.3;
795 ge_cairo_set_color (cr, &border);
796 cairo_stroke (cr);
797 }
798 }
799
800 static void
clearlooks_draw_slider_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)801 clearlooks_draw_slider_button (cairo_t *cr,
802 const ClearlooksColors *colors,
803 const WidgetParameters *params,
804 const SliderParameters *slider,
805 int x, int y, int width, int height)
806 {
807 double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
808
809 cairo_save (cr);
810 cairo_set_line_width (cr, 1.0);
811
812 if (!slider->horizontal)
813 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
814 cairo_translate (cr, x, y);
815
816 params->style_functions->draw_shadow (cr, colors, radius, width, height);
817 params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2);
818
819 if (width > 24)
820 params->style_functions->draw_gripdots (cr, colors, 1, 1, width-2, height-2, 3, 3, 0);
821
822 cairo_restore (cr);
823 }
824
825 static void
clearlooks_draw_progressbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)826 clearlooks_draw_progressbar_trough (cairo_t *cr,
827 const ClearlooksColors *colors,
828 const WidgetParameters *params,
829 int x, int y, int width, int height)
830 {
831 const CairoColor *border = &colors->shade[4];
832 CairoColor shadow;
833 cairo_pattern_t *pattern;
834 double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0));
835
836 cairo_save (cr);
837
838 cairo_set_line_width (cr, 1.0);
839
840 /* Create trough box */
841 ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
842 ge_cairo_set_color (cr, &colors->shade[2]);
843 cairo_fill (cr);
844
845 /* Draw border */
846 ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners);
847 ge_cairo_set_color (cr, border);
848 cairo_stroke (cr);
849
850 /* clip the corners of the shadows */
851 ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
852 cairo_clip (cr);
853
854 ge_shade_color (border, 0.925, &shadow);
855
856 /* Top shadow */
857 cairo_rectangle (cr, x+1, y+1, width-2, 4);
858 pattern = cairo_pattern_create_linear (x, y, x, y+4);
859 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2);
860 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0);
861 cairo_set_source (cr, pattern);
862 cairo_fill (cr);
863 cairo_pattern_destroy (pattern);
864
865 /* Left shadow */
866 cairo_rectangle (cr, x+1, y+1, 4, height-2);
867 pattern = cairo_pattern_create_linear (x, y, x+4, y);
868 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2);
869 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0);
870 cairo_set_source (cr, pattern);
871 cairo_fill (cr);
872 cairo_pattern_destroy (pattern);
873
874 cairo_restore (cr);
875 }
876
877 static void
clearlooks_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)878 clearlooks_draw_progressbar_fill (cairo_t *cr,
879 const ClearlooksColors *colors,
880 const WidgetParameters *params,
881 const ProgressBarParameters *progressbar,
882 int x, int y, int width, int height,
883 gint offset)
884 {
885 boolean is_horizontal = progressbar->orientation < 2;
886 double tile_pos = 0;
887 double stroke_width;
888 double radius;
889 int x_step;
890
891 cairo_pattern_t *pattern;
892 CairoColor bg_shade;
893 CairoColor border;
894 CairoColor shadow;
895
896 radius = MAX (0, params->radius - params->xthickness);
897
898 cairo_save (cr);
899
900 if (!is_horizontal)
901 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
902
903 if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
904 ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
905
906 /* Clamp the radius so that the _height_ fits ... */
907 radius = MIN (radius, height / 2.0);
908
909 stroke_width = height;
910 x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
911
912 cairo_translate (cr, x, y);
913
914 cairo_save (cr);
915 /* This is kind of nasty ... Clip twice from each side in case the length
916 * of the fill is smaller than twice the radius. */
917 ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
918 cairo_clip (cr);
919 ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
920 cairo_clip (cr);
921
922 /* Draw the background gradient */
923 ge_shade_color (&colors->spot[1], 1.1, &bg_shade);
924
925 /* Just leave this disabled, maybe we could use the same gradient
926 * as the buttons in the future, not flat fill */
927 /* pattern = cairo_pattern_create_linear (0, 0, 0, height);*/
928 /* cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b);*/
929 /* cairo_pattern_add_color_stop_rgb (pattern, 0.6, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);*/
930 /* cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b);*/
931 /* cairo_set_source (cr, pattern);*/
932 /* cairo_paint (cr);*/
933 /* cairo_pattern_destroy (pattern);*/
934
935 ge_cairo_set_color (cr, &bg_shade);
936 cairo_paint (cr);
937
938 /* Draw the Strokes */
939 while (stroke_width > 0 && tile_pos <= width+x_step)
940 {
941 cairo_move_to (cr, stroke_width/2-x_step, 0);
942 cairo_line_to (cr, stroke_width-x_step, 0);
943 cairo_line_to (cr, stroke_width/2-x_step, height);
944 cairo_line_to (cr, -x_step, height);
945
946 cairo_translate (cr, stroke_width, 0);
947 tile_pos += stroke_width;
948 }
949
950 pattern = cairo_pattern_create_linear (0, 0, 0, height);
951 cairo_pattern_add_color_stop_rgba (pattern, 0.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0);
952 cairo_pattern_add_color_stop_rgba (pattern, 1.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0.24);
953 cairo_set_source (cr, pattern);
954 cairo_fill (cr);
955 cairo_pattern_destroy (pattern);
956
957 cairo_restore (cr); /* rounded clip region */
958
959 /* Draw the dark lines and the shadow */
960 cairo_save (cr);
961 /* Again, this weird clip area. */
962 ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
963 cairo_clip (cr);
964 ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
965 cairo_clip (cr);
966
967 shadow.r = 0.0;
968 shadow.g = 0.0;
969 shadow.b = 0.0;
970 shadow.a = 0.1;
971
972 if (progressbar->pulsing)
973 {
974 /* At the beginning of the bar. */
975 cairo_move_to (cr, -0.5 + radius, height + 0.5);
976 ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
977 ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
978 ge_cairo_set_color (cr, &shadow);
979 cairo_stroke (cr);
980 }
981 if (progressbar->value < 1.0 || progressbar->pulsing)
982 {
983 /* At the end of the bar. */
984 cairo_move_to (cr, width + 0.5 - radius, -0.5);
985 ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
986 ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
987 ge_cairo_set_color (cr, &shadow);
988 cairo_stroke (cr);
989 }
990
991 /* ge_cairo_rounded_rectangle (cr, 1.5,1.5, width-2, height-2, radius, CR_CORNER_ALL);*/
992 /* cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 1);*/
993 /* cairo_stroke (cr);*/
994
995 params->style_functions->draw_top_left_highlight (cr, &colors->spot[1], params, 1.5, 1.5,
996 width - 1, height - 1,
997 radius, params->corners);
998
999 border = colors->spot[2];
1000 border.a = 0.6;
1001 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, CR_CORNER_ALL);
1002 ge_cairo_set_color (cr, &border);
1003 cairo_stroke (cr);
1004
1005 cairo_restore (cr);
1006
1007 cairo_restore (cr); /* rotation, mirroring */
1008 }
1009
1010 static void
clearlooks_draw_optionmenu(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const OptionMenuParameters * optionmenu,int x,int y,int width,int height)1011 clearlooks_draw_optionmenu (cairo_t *cr,
1012 const ClearlooksColors *colors,
1013 const WidgetParameters *params,
1014 const OptionMenuParameters *optionmenu,
1015 int x, int y, int width, int height)
1016 {
1017 SeparatorParameters separator;
1018 int offset = params->ythickness + 2;
1019
1020 params->style_functions->draw_button (cr, colors, params, x, y, width, height);
1021
1022 separator.horizontal = FALSE;
1023 params->style_functions->draw_separator (cr, colors, params, &separator, x+optionmenu->linepos, y + offset, 2, height - offset*2);
1024 }
1025
1026 static void
clearlooks_draw_menu_item_separator(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1027 clearlooks_draw_menu_item_separator (cairo_t *cr,
1028 const ClearlooksColors *colors,
1029 const WidgetParameters *widget,
1030 const SeparatorParameters *separator,
1031 int x, int y, int width, int height)
1032 {
1033 cairo_save (cr);
1034 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1035 ge_cairo_set_color (cr, &colors->shade[5]);
1036
1037 if (separator->horizontal)
1038 cairo_rectangle (cr, x, y, width, 1);
1039 else
1040 cairo_rectangle (cr, x, y, 1, height);
1041
1042 cairo_fill (cr);
1043
1044 cairo_restore (cr);
1045 }
1046
1047 static void
clearlooks_draw_menubar0(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1048 clearlooks_draw_menubar0 (cairo_t *cr,
1049 const ClearlooksColors *colors,
1050 const WidgetParameters *params,
1051 const MenuBarParameters *menubar,
1052 int x, int y, int width, int height)
1053 {
1054 const CairoColor *dark = &colors->shade[3];
1055
1056 cairo_save (cr);
1057
1058 cairo_set_line_width (cr, 1);
1059 cairo_translate (cr, x, y);
1060
1061 cairo_move_to (cr, 0, height-0.5);
1062 cairo_line_to (cr, width, height-0.5);
1063 ge_cairo_set_color (cr, dark);
1064 cairo_stroke (cr);
1065
1066 cairo_restore (cr);
1067 }
1068
1069 static void
clearlooks_draw_menubar2(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1070 clearlooks_draw_menubar2 (cairo_t *cr,
1071 const ClearlooksColors *colors,
1072 const WidgetParameters *params,
1073 const MenuBarParameters *menubar,
1074 int x, int y, int width, int height)
1075 {
1076 CairoColor lower;
1077 cairo_pattern_t *pattern;
1078
1079 cairo_save (cr);
1080
1081 ge_shade_color (&colors->bg[0], 0.96, &lower);
1082
1083 cairo_translate (cr, x, y);
1084 cairo_rectangle (cr, 0, 0, width, height);
1085
1086 /* Draw the gradient */
1087 pattern = cairo_pattern_create_linear (0, 0, 0, height);
1088 cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r,
1089 colors->bg[0].g,
1090 colors->bg[0].b);
1091 cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r,
1092 lower.g,
1093 lower.b);
1094 cairo_set_source (cr, pattern);
1095 cairo_fill (cr);
1096 cairo_pattern_destroy (pattern);
1097
1098 /* Draw bottom line */
1099 cairo_set_line_width (cr, 1.0);
1100 cairo_move_to (cr, 0, height-0.5);
1101 cairo_line_to (cr, width, height-0.5);
1102 ge_cairo_set_color (cr, &colors->shade[3]);
1103 cairo_stroke (cr);
1104
1105 cairo_restore (cr);
1106 }
1107
1108 static void
clearlooks_draw_menubar1(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1109 clearlooks_draw_menubar1 (cairo_t *cr,
1110 const ClearlooksColors *colors,
1111 const WidgetParameters *params,
1112 const MenuBarParameters *menubar,
1113 int x, int y, int width, int height)
1114 {
1115 const CairoColor *border = &colors->shade[3];
1116
1117 clearlooks_draw_menubar2 (cr, colors, params, menubar,
1118 x, y, width, height);
1119
1120 ge_cairo_set_color (cr, border);
1121 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1122 }
1123
1124
1125 static menubar_draw_proto clearlooks_menubar_draw[3] =
1126 {
1127 clearlooks_draw_menubar0,
1128 clearlooks_draw_menubar1,
1129 clearlooks_draw_menubar2
1130 };
1131
1132 static void
clearlooks_draw_menubar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1133 clearlooks_draw_menubar (cairo_t *cr,
1134 const ClearlooksColors *colors,
1135 const WidgetParameters *params,
1136 const MenuBarParameters *menubar,
1137 int x, int y, int width, int height)
1138 {
1139 if (menubar->style < 0 || menubar->style >= G_N_ELEMENTS (clearlooks_menubar_draw))
1140 return;
1141
1142 clearlooks_menubar_draw[menubar->style](cr, colors, params, menubar,
1143 x, y, width, height);
1144 }
1145
1146 static void
clearlooks_get_frame_gap_clip(int x,int y,int width,int height,const FrameParameters * frame,ClearlooksRectangle * bevel,ClearlooksRectangle * border)1147 clearlooks_get_frame_gap_clip (int x, int y, int width, int height,
1148 const FrameParameters *frame,
1149 ClearlooksRectangle *bevel,
1150 ClearlooksRectangle *border)
1151 {
1152 if (frame->gap_side == CL_GAP_TOP)
1153 {
1154 CLEARLOOKS_RECTANGLE_SET (*bevel, 2.0 + frame->gap_x, 0.0,
1155 frame->gap_width - 3, 2.0);
1156 CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x, 0.0,
1157 frame->gap_width - 2, 2.0);
1158 }
1159 else if (frame->gap_side == CL_GAP_BOTTOM)
1160 {
1161 CLEARLOOKS_RECTANGLE_SET (*bevel, 2.0 + frame->gap_x, height - 2.0,
1162 frame->gap_width - 3, 2.0);
1163 CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x, height - 1.0,
1164 frame->gap_width - 2, 2.0);
1165 }
1166 else if (frame->gap_side == CL_GAP_LEFT)
1167 {
1168 CLEARLOOKS_RECTANGLE_SET (*bevel, 0.0, 2.0 + frame->gap_x,
1169 2.0, frame->gap_width - 3);
1170 CLEARLOOKS_RECTANGLE_SET (*border, 0.0, 1.0 + frame->gap_x,
1171 1.0, frame->gap_width - 2);
1172 }
1173 else if (frame->gap_side == CL_GAP_RIGHT)
1174 {
1175 CLEARLOOKS_RECTANGLE_SET (*bevel, width - 2.0, 2.0 + frame->gap_x,
1176 2.0, frame->gap_width - 3);
1177 CLEARLOOKS_RECTANGLE_SET (*border, width - 1.0, 1.0 + frame->gap_x,
1178 1.0, frame->gap_width - 2);
1179 }
1180 }
1181
1182 static void
clearlooks_draw_frame(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const FrameParameters * frame,int x,int y,int width,int height)1183 clearlooks_draw_frame (cairo_t *cr,
1184 const ClearlooksColors *colors,
1185 const WidgetParameters *params,
1186 const FrameParameters *frame,
1187 int x, int y, int width, int height)
1188 {
1189 const CairoColor *border = frame->border;
1190 const CairoColor *dark = (CairoColor*)&colors->shade[4];
1191 ClearlooksRectangle bevel_clip = {0, 0, 0, 0};
1192 ClearlooksRectangle frame_clip = {0, 0, 0, 0};
1193 double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1194 CairoColor hilight;
1195
1196 ge_shade_color (&colors->bg[0], 1.05, &hilight);
1197
1198 if (frame->shadow == CL_SHADOW_NONE)
1199 return;
1200
1201 if (frame->gap_x != -1)
1202 clearlooks_get_frame_gap_clip (x, y, width, height,
1203 frame, &bevel_clip, &frame_clip);
1204
1205 cairo_set_line_width (cr, 1.0);
1206 cairo_translate (cr, x, y);
1207
1208 /* save everything */
1209 cairo_save (cr);
1210 /* Set clip for the bevel */
1211 if (frame->gap_x != -1)
1212 {
1213 /* Set clip for gap */
1214 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1215 cairo_rectangle (cr, 0, 0, width, height);
1216 cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
1217 cairo_clip (cr);
1218 }
1219
1220 /* Draw the bevel */
1221 if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
1222 {
1223 ge_cairo_set_color (cr, &hilight);
1224 if (frame->shadow == CL_SHADOW_ETCHED_IN)
1225 ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners);
1226 else
1227 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
1228 cairo_stroke (cr);
1229 }
1230 else if (frame->shadow != CL_SHADOW_NONE)
1231 {
1232 ShadowParameters shadow;
1233 shadow.corners = params->corners;
1234 shadow.shadow = frame->shadow;
1235 clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, radius);
1236 }
1237
1238 /* restore the previous clip region */
1239 cairo_restore (cr);
1240 cairo_save (cr);
1241 if (frame->gap_x != -1)
1242 {
1243 /* Set clip for gap */
1244 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1245 cairo_rectangle (cr, 0, 0, width, height);
1246 cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
1247 cairo_clip (cr);
1248 }
1249
1250 /* Draw frame */
1251 if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
1252 {
1253 ge_cairo_set_color (cr, dark);
1254 if (frame->shadow == CL_SHADOW_ETCHED_IN)
1255 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
1256 else
1257 ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners);
1258 }
1259 else
1260 {
1261 ge_cairo_set_color (cr, border);
1262 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
1263 }
1264 cairo_stroke (cr);
1265
1266 cairo_restore (cr);
1267 }
1268
1269 static void
clearlooks_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)1270 clearlooks_draw_tab (cairo_t *cr,
1271 const ClearlooksColors *colors,
1272 const WidgetParameters *params,
1273 const TabParameters *tab,
1274 int x, int y, int width, int height)
1275 {
1276 const CairoColor *border1 = &colors->shade[6];
1277 const CairoColor *border2 = &colors->shade[5];
1278 const CairoColor *stripe_fill = &colors->spot[1];
1279 const CairoColor *stripe_border = &colors->spot[2];
1280 const CairoColor *fill;
1281 CairoColor hilight;
1282
1283 cairo_pattern_t *pattern;
1284
1285 double radius;
1286 double stripe_size = 2.0;
1287 double stripe_fill_size;
1288 double length;
1289
1290 radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1291
1292 cairo_save (cr);
1293
1294 /* Set clip */
1295 cairo_rectangle (cr, x, y, width, height);
1296 cairo_clip (cr);
1297 cairo_new_path (cr);
1298
1299 /* Translate and set line width */
1300 cairo_set_line_width (cr, 1.0);
1301 cairo_translate (cr, x, y);
1302
1303
1304 /* Make the tabs slightly bigger than they should be, to create a gap */
1305 /* And calculate the strip size too, while you're at it */
1306 if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
1307 {
1308 height += 3.0;
1309 length = height;
1310 stripe_fill_size = (tab->gap_side == CL_GAP_TOP ? stripe_size/height : stripe_size/(height-2));
1311
1312 if (tab->gap_side == CL_GAP_TOP)
1313 cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
1314 }
1315 else
1316 {
1317 width += 3.0;
1318 length = width;
1319 stripe_fill_size = (tab->gap_side == CL_GAP_LEFT ? stripe_size/width : stripe_size/(width-2));
1320
1321 if (tab->gap_side == CL_GAP_LEFT)
1322 cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
1323 }
1324
1325 /* Set the fill color */
1326 fill = &colors->bg[params->state_type];
1327
1328 /* Set tab shape */
1329 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1,
1330 radius, params->corners);
1331
1332 /* Draw fill */
1333 ge_cairo_set_color (cr, fill);
1334 cairo_fill (cr);
1335
1336
1337 ge_shade_color (fill, 1.3, &hilight);
1338
1339 /* Draw highlight */
1340 if (!params->active)
1341 {
1342 ShadowParameters shadow;
1343
1344 shadow.shadow = CL_SHADOW_OUT;
1345 shadow.corners = params->corners;
1346
1347 clearlooks_draw_highlight_and_shade (cr, colors, &shadow,
1348 width,
1349 height, radius);
1350 }
1351
1352 if (params->active)
1353 {
1354 CairoColor shadow;
1355 switch (tab->gap_side)
1356 {
1357 case CL_GAP_TOP:
1358 pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5);
1359 break;
1360 case CL_GAP_BOTTOM:
1361 pattern = cairo_pattern_create_linear (0.5, 1.5, 0.5, height+0.5);
1362 break;
1363 case CL_GAP_LEFT:
1364 pattern = cairo_pattern_create_linear (width-1.5, 0.5, 1.5, 0.5);
1365 break;
1366 case CL_GAP_RIGHT:
1367 pattern = cairo_pattern_create_linear (1.5, 0.5, width-1.5, 0.5);
1368 break;
1369 default:
1370 pattern = NULL;
1371 }
1372
1373 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners);
1374
1375 ge_shade_color (fill, 0.92, &shadow);
1376
1377 cairo_pattern_add_color_stop_rgba (pattern, 0.0, hilight.r, hilight.g, hilight.b, 0.4);
1378 cairo_pattern_add_color_stop_rgba (pattern, 1.0/length, hilight.r, hilight.g, hilight.b, 0.4);
1379 cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, fill->r,fill->g,fill->b);
1380 cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r,shadow.g,shadow.b);
1381 cairo_set_source (cr, pattern);
1382 cairo_fill (cr);
1383 cairo_pattern_destroy (pattern);
1384 }
1385 else
1386 {
1387 /* Draw shade */
1388 switch (tab->gap_side)
1389 {
1390 case CL_GAP_TOP:
1391 pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5);
1392 break;
1393 case CL_GAP_BOTTOM:
1394 pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, height+0.5);
1395 break;
1396 case CL_GAP_LEFT:
1397 pattern = cairo_pattern_create_linear (width-1.5, 0.5, 0.5, 0.5);
1398 break;
1399 case CL_GAP_RIGHT:
1400 pattern = cairo_pattern_create_linear (0.5, 0.5, width+0.5, 0.5);
1401 break;
1402 default:
1403 pattern = NULL;
1404 }
1405
1406 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners);
1407
1408 cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b);
1409 cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
1410 cairo_pattern_add_color_stop_rgba (pattern, stripe_fill_size, hilight.r, hilight.g, hilight.b, 0.5);
1411 cairo_pattern_add_color_stop_rgba (pattern, 0.8, hilight.r, hilight.g, hilight.b, 0.0);
1412 cairo_set_source (cr, pattern);
1413 cairo_fill (cr);
1414 cairo_pattern_destroy (pattern);
1415 }
1416
1417 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
1418
1419 if (params->active)
1420 {
1421 ge_cairo_set_color (cr, border2);
1422 cairo_stroke (cr);
1423 }
1424 else
1425 {
1426 switch (tab->gap_side)
1427 {
1428 case CL_GAP_TOP:
1429 pattern = cairo_pattern_create_linear (2.5, height-1.5, 2.5, 2.5);
1430 break;
1431 case CL_GAP_BOTTOM:
1432 pattern = cairo_pattern_create_linear (2.5, 2.5, 2.5, height+0.5);
1433 break;
1434 case CL_GAP_LEFT:
1435 pattern = cairo_pattern_create_linear (width-1.5, 2.5, 2.5, 2.5);
1436 break;
1437 case CL_GAP_RIGHT:
1438 pattern = cairo_pattern_create_linear (2.5, 2.5, width+0.5, 2.5);
1439 break;
1440 default:
1441 pattern = NULL;
1442 }
1443
1444 cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
1445 cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_border->r, stripe_border->g, stripe_border->b);
1446 cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, border1->r, border1->g, border1->b);
1447 cairo_pattern_add_color_stop_rgb (pattern, 1.0, border2->r, border2->g, border2->b);
1448 cairo_set_source (cr, pattern);
1449 cairo_stroke (cr);
1450 cairo_pattern_destroy (pattern);
1451 }
1452
1453 cairo_restore (cr);
1454 }
1455
1456 static void
clearlooks_draw_separator(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1457 clearlooks_draw_separator (cairo_t *cr,
1458 const ClearlooksColors *colors,
1459 const WidgetParameters *widget,
1460 const SeparatorParameters *separator,
1461 int x, int y, int width, int height)
1462 {
1463 CairoColor color = colors->shade[2];
1464 CairoColor hilight;
1465 ge_shade_color (&colors->bg[0], 1.065, &hilight);
1466
1467 cairo_save (cr);
1468 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1469
1470 if (separator->horizontal)
1471 {
1472 cairo_set_line_width (cr, 1.0);
1473 cairo_translate (cr, x, y+0.5);
1474
1475 cairo_move_to (cr, 0.0, 0.0);
1476 cairo_line_to (cr, width, 0.0);
1477 ge_cairo_set_color (cr, &color);
1478 cairo_stroke (cr);
1479
1480 cairo_move_to (cr, 0.0, 1.0);
1481 cairo_line_to (cr, width, 1.0);
1482 ge_cairo_set_color (cr, &hilight);
1483 cairo_stroke (cr);
1484 }
1485 else
1486 {
1487 cairo_set_line_width (cr, 1.0);
1488 cairo_translate (cr, x+0.5, y);
1489
1490 cairo_move_to (cr, 0.0, 0.0);
1491 cairo_line_to (cr, 0.0, height);
1492 ge_cairo_set_color (cr, &color);
1493 cairo_stroke (cr);
1494
1495 cairo_move_to (cr, 1.0, 0.0);
1496 cairo_line_to (cr, 1.0, height);
1497 ge_cairo_set_color (cr, &hilight);
1498 cairo_stroke (cr);
1499 }
1500
1501 cairo_restore (cr);
1502 }
1503
1504 static void
clearlooks_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)1505 clearlooks_draw_list_view_header (cairo_t *cr,
1506 const ClearlooksColors *colors,
1507 const WidgetParameters *params,
1508 const ListViewHeaderParameters *header,
1509 int x, int y, int width, int height)
1510 {
1511 const CairoColor *border = &colors->shade[4];
1512 CairoColor hilight;
1513
1514 ge_shade_color (&colors->bg[params->state_type],
1515 params->style_constants->topleft_highlight_shade, &hilight);
1516 hilight.a = params->style_constants->topleft_highlight_alpha;
1517
1518 cairo_translate (cr, x, y);
1519 cairo_set_line_width (cr, 1.0);
1520
1521 /* Draw highlight */
1522 if (header->order & CL_ORDER_FIRST)
1523 {
1524 cairo_move_to (cr, 0.5, height-1);
1525 cairo_line_to (cr, 0.5, 0.5);
1526 }
1527 else
1528 cairo_move_to (cr, 0.0, 0.5);
1529
1530 cairo_line_to (cr, width, 0.5);
1531
1532 ge_cairo_set_color (cr, &hilight);
1533 cairo_stroke (cr);
1534
1535 /* Draw bottom border */
1536 cairo_move_to (cr, 0.0, height-0.5);
1537 cairo_line_to (cr, width, height-0.5);
1538 ge_cairo_set_color (cr, border);
1539 cairo_stroke (cr);
1540
1541 /* Draw resize grip */
1542 if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
1543 (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
1544 {
1545 SeparatorParameters separator;
1546 separator.horizontal = FALSE;
1547
1548 if (params->ltr)
1549 params->style_functions->draw_separator (cr, colors, params, &separator,
1550 width-1.5, 4.0, 2, height-8.0);
1551 else
1552 params->style_functions->draw_separator (cr, colors, params, &separator,
1553 1.5, 4.0, 2, height-8.0);
1554 }
1555 }
1556
1557 /* We can't draw transparent things here, since it will be called on the same
1558 * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
1559 static void
clearlooks_draw_toolbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1560 clearlooks_draw_toolbar (cairo_t *cr,
1561 const ClearlooksColors *colors,
1562 const WidgetParameters *widget,
1563 const ToolbarParameters *toolbar,
1564 int x, int y, int width, int height)
1565 {
1566 const CairoColor *fill = &colors->bg[0];
1567 const CairoColor *dark = &colors->shade[3];
1568 CairoColor light;
1569 ge_shade_color (fill, 1.065, &light);
1570
1571 cairo_set_line_width (cr, 1.0);
1572 cairo_translate (cr, x, y);
1573
1574 ge_cairo_set_color (cr, fill);
1575 cairo_paint (cr);
1576
1577 if (!toolbar->topmost)
1578 {
1579 /* Draw highlight */
1580 cairo_move_to (cr, 0, 0.5);
1581 cairo_line_to (cr, width-1, 0.5);
1582 ge_cairo_set_color (cr, &light);
1583 cairo_stroke (cr);
1584 }
1585
1586 /* Draw shadow */
1587 cairo_move_to (cr, 0, height-0.5);
1588 cairo_line_to (cr, width-1, height-0.5);
1589 ge_cairo_set_color (cr, dark);
1590 cairo_stroke (cr);
1591 }
1592
1593 static void
clearlooks_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1594 clearlooks_draw_menuitem (cairo_t *cr,
1595 const ClearlooksColors *colors,
1596 const WidgetParameters *widget,
1597 int x, int y, int width, int height)
1598 {
1599 const CairoColor *fill = &colors->spot[1];
1600 CairoColor fill_shade;
1601 CairoColor border = colors->spot[2];
1602 cairo_pattern_t *pattern;
1603
1604 ge_shade_color (&border, 1.05, &border);
1605 ge_shade_color (fill, 0.85, &fill_shade);
1606 cairo_set_line_width (cr, 1.0);
1607
1608 ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, widget->radius, widget->corners);
1609
1610 pattern = cairo_pattern_create_linear (x, y, x, y + height);
1611 cairo_pattern_add_color_stop_rgb (pattern, 0, fill->r, fill->g, fill->b);
1612 cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b);
1613
1614 cairo_set_source (cr, pattern);
1615 cairo_fill_preserve (cr);
1616 cairo_pattern_destroy (pattern);
1617
1618 ge_cairo_set_color (cr, &border);
1619 cairo_stroke (cr);
1620 }
1621
1622 static void
clearlooks_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1623 clearlooks_draw_menubaritem (cairo_t *cr,
1624 const ClearlooksColors *colors,
1625 const WidgetParameters *widget,
1626 int x, int y, int width, int height)
1627 {
1628 const CairoColor *fill = &colors->spot[1];
1629 CairoColor fill_shade;
1630 CairoColor border = colors->spot[2];
1631 cairo_pattern_t *pattern;
1632
1633 ge_shade_color (&border, 1.05, &border);
1634 ge_shade_color (fill, 0.85, &fill_shade);
1635
1636 cairo_set_line_width (cr, 1.0);
1637 ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners);
1638
1639 pattern = cairo_pattern_create_linear (x, y, x, y + height);
1640 cairo_pattern_add_color_stop_rgb (pattern, 0, fill->r, fill->g, fill->b);
1641 cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b);
1642
1643 cairo_set_source (cr, pattern);
1644 cairo_fill_preserve (cr);
1645 cairo_pattern_destroy (pattern);
1646
1647 ge_cairo_set_color (cr, &border);
1648 cairo_stroke_preserve (cr);
1649 }
1650
1651 static void
clearlooks_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1652 clearlooks_draw_selected_cell (cairo_t *cr,
1653 const ClearlooksColors *colors,
1654 const WidgetParameters *params,
1655 int x, int y, int width, int height)
1656 {
1657 CairoColor upper_color;
1658 CairoColor lower_color;
1659 cairo_pattern_t *pattern;
1660 cairo_save (cr);
1661
1662 cairo_translate (cr, x, y);
1663
1664 if (params->focus)
1665 upper_color = colors->base[params->state_type];
1666 else
1667 upper_color = colors->base[GTK_STATE_ACTIVE];
1668
1669 ge_shade_color(&upper_color, 0.92, &lower_color);
1670
1671 pattern = cairo_pattern_create_linear (0, 0, 0, height);
1672 cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r,
1673 upper_color.g,
1674 upper_color.b);
1675 cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r,
1676 lower_color.g,
1677 lower_color.b);
1678
1679 cairo_set_source (cr, pattern);
1680 cairo_rectangle (cr, 0, 0, width, height);
1681 cairo_fill (cr);
1682
1683 cairo_pattern_destroy (pattern);
1684
1685 cairo_restore (cr);
1686 }
1687
1688
1689 static void
clearlooks_draw_scrollbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1690 clearlooks_draw_scrollbar_trough (cairo_t *cr,
1691 const ClearlooksColors *colors,
1692 const WidgetParameters *widget,
1693 const ScrollBarParameters *scrollbar,
1694 int x, int y, int width, int height)
1695 {
1696 const CairoColor *bg = &colors->shade[2];
1697 const CairoColor *border = &colors->shade[5];
1698 CairoColor bg_shade;
1699 cairo_pattern_t *pattern;
1700 double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1701
1702 ge_shade_color (bg, 0.95, &bg_shade);
1703
1704 cairo_set_line_width (cr, 1);
1705 /* cairo_translate (cr, x, y); */
1706
1707 if (scrollbar->horizontal)
1708 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1709
1710 cairo_translate (cr, x, y);
1711
1712 /* Draw fill */
1713 if (radius > 3.0)
1714 ge_cairo_rounded_rectangle (cr, 1, 0, width-2, height,
1715 radius, widget->corners);
1716 else
1717 cairo_rectangle (cr, 1, 0, width-2, height);
1718 ge_cairo_set_color (cr, bg);
1719 cairo_fill (cr);
1720
1721 /* Draw shadow */
1722 pattern = cairo_pattern_create_linear (1, 0, 3, 0);
1723 cairo_pattern_add_color_stop_rgb (pattern, 0, bg_shade.r, bg_shade.g, bg_shade.b);
1724 cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r, bg->g, bg->b);
1725 cairo_rectangle (cr, 1, 0, 4, height);
1726 cairo_set_source (cr, pattern);
1727 cairo_fill (cr);
1728 cairo_pattern_destroy (pattern);
1729
1730 /* Draw border */
1731 if (radius > 3.0)
1732 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1,
1733 radius, widget->corners);
1734 else
1735 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1736 ge_cairo_set_color (cr, border);
1737 cairo_stroke (cr);
1738 }
1739
1740 static void
clearlooks_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)1741 clearlooks_draw_scrollbar_stepper (cairo_t *cr,
1742 const ClearlooksColors *colors,
1743 const WidgetParameters *widget,
1744 const ScrollBarParameters *scrollbar,
1745 const ScrollBarStepperParameters *stepper,
1746 int x, int y, int width, int height)
1747 {
1748 CairoCorners corners = CR_CORNER_NONE;
1749 CairoColor border;
1750 CairoColor s1, s2, s3, s4;
1751 cairo_pattern_t *pattern;
1752 double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1753
1754 ge_shade_color(&colors->shade[6], 1.08, &border);
1755
1756 if (scrollbar->horizontal)
1757 {
1758 if (stepper->stepper == CL_STEPPER_A)
1759 corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
1760 else if (stepper->stepper == CL_STEPPER_D)
1761 corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
1762
1763 if (stepper->stepper == CL_STEPPER_B)
1764 {
1765 x -= 1;
1766 width += 1;
1767 }
1768 else if (stepper->stepper == CL_STEPPER_C)
1769 {
1770 width += 1;
1771 }
1772 }
1773 else
1774 {
1775 if (stepper->stepper == CL_STEPPER_A)
1776 corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
1777 else if (stepper->stepper == CL_STEPPER_D)
1778 corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
1779
1780 if (stepper->stepper == CL_STEPPER_B)
1781 {
1782 y -= 1;
1783 height += 1;
1784 }
1785 else if (stepper->stepper == CL_STEPPER_C)
1786 {
1787 height += 1;
1788 }
1789 }
1790
1791 cairo_translate (cr, x, y);
1792 cairo_set_line_width (cr, 1);
1793
1794 ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
1795
1796 if (scrollbar->horizontal)
1797 pattern = cairo_pattern_create_linear (0, 0, 0, height);
1798 else
1799 pattern = cairo_pattern_create_linear (0, 0, width, 0);
1800
1801 ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1);
1802 ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2);
1803 ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3);
1804 ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4);
1805
1806 cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b);
1807 cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b);
1808 cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b);
1809 cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b);
1810 cairo_set_source (cr, pattern);
1811 cairo_fill (cr);
1812 cairo_pattern_destroy (pattern);
1813
1814 widget->style_functions->draw_top_left_highlight (cr, &s2, widget, 1, 1, width - 2, height - 2, MAX(radius - 1, 0), corners);
1815
1816 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners);
1817 clearlooks_set_border_gradient (cr, &border, 1.1, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0));
1818 cairo_stroke (cr);
1819 }
1820
1821 static void
clearlooks_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1822 clearlooks_draw_scrollbar_slider (cairo_t *cr,
1823 const ClearlooksColors *colors,
1824 const WidgetParameters *widget,
1825 const ScrollBarParameters *scrollbar,
1826 int x, int y, int width, int height)
1827 {
1828 cairo_save (cr);
1829
1830 if (scrollbar->junction & CL_JUNCTION_BEGIN)
1831 {
1832 if (scrollbar->horizontal)
1833 {
1834 x -= 1;
1835 width += 1;
1836 }
1837 else
1838 {
1839 y -= 1;
1840 height += 1;
1841 }
1842 }
1843 if (scrollbar->junction & CL_JUNCTION_END)
1844 {
1845 if (scrollbar->horizontal)
1846 width += 1;
1847 else
1848 height += 1;
1849 }
1850
1851 if (!scrollbar->horizontal)
1852 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1853
1854 cairo_translate (cr, x, y);
1855
1856 if (scrollbar->has_color)
1857 {
1858 const CairoColor *border = &colors->shade[7];
1859 CairoColor fill = scrollbar->color;
1860 CairoColor hilight;
1861 CairoColor shade1, shade2, shade3;
1862 cairo_pattern_t *pattern;
1863
1864 if (widget->prelight)
1865 ge_shade_color (&fill, 1.1, &fill);
1866
1867 cairo_set_line_width (cr, 1);
1868
1869 ge_shade_color (&fill, 1.3, &hilight);
1870 ge_shade_color (&fill, 1.1, &shade1);
1871 ge_shade_color (&fill, 1.05, &shade2);
1872 ge_shade_color (&fill, 0.98, &shade3);
1873
1874 pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
1875 cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b);
1876 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1877 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b);
1878 cairo_pattern_add_color_stop_rgb (pattern, 1, fill.r, fill.g, fill.b);
1879 cairo_rectangle (cr, 1, 1, width-2, height-2);
1880 cairo_set_source (cr, pattern);
1881 cairo_fill (cr);
1882 cairo_pattern_destroy (pattern);
1883
1884 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1885 ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
1886
1887 ge_cairo_set_color (cr, border);
1888 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1889 }
1890 else
1891 {
1892 const CairoColor *dark = &colors->shade[4];
1893 const CairoColor *light = &colors->shade[0];
1894 CairoColor border;
1895 CairoColor s1, s2, s3, s4, s5;
1896 cairo_pattern_t *pattern;
1897 int bar_x, i;
1898
1899 ge_shade_color (&colors->shade[6], 1.08, &border);
1900 ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1);
1901 ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2);
1902 ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3);
1903 ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4);
1904
1905 pattern = cairo_pattern_create_linear(1, 1, 1, height-1);
1906 cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b);
1907 cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b);
1908 cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b);
1909 cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b);
1910
1911 cairo_rectangle (cr, 1, 1, width-2, height-2);
1912 cairo_set_source(cr, pattern);
1913 cairo_fill(cr);
1914 cairo_pattern_destroy(pattern);
1915
1916 clearlooks_set_border_gradient (cr, &border, 1.1, 0, height);
1917 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1918
1919 cairo_move_to (cr, 1.5, height-1.5);
1920 cairo_line_to (cr, 1.5, 1.5);
1921 cairo_line_to (cr, width-1.5, 1.5);
1922 ge_shade_color (&s2, widget->style_constants->topleft_highlight_shade, &s5);
1923 s5.a = widget->style_constants->topleft_highlight_alpha;
1924 ge_cairo_set_color (cr, &s5);
1925 cairo_stroke(cr);
1926
1927 /* draw handles */
1928 cairo_set_line_width (cr, 1);
1929 cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1930
1931 bar_x = width/2 - 4;
1932
1933 for (i=0; i<3; i++)
1934 {
1935 cairo_move_to (cr, bar_x + 0.5, 4);
1936 cairo_line_to (cr, bar_x + 0.5, height-4);
1937 ge_cairo_set_color (cr, dark);
1938 cairo_stroke (cr);
1939
1940 cairo_move_to (cr, bar_x+1.5, 4);
1941 cairo_line_to (cr, bar_x+1.5, height-4);
1942 ge_cairo_set_color (cr, light);
1943 cairo_stroke (cr);
1944
1945 bar_x += 3;
1946 }
1947 }
1948
1949 cairo_restore (cr);
1950 }
1951
1952 static void
clearlooks_draw_statusbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1953 clearlooks_draw_statusbar (cairo_t *cr,
1954 const ClearlooksColors *colors,
1955 const WidgetParameters *widget,
1956 int x, int y, int width, int height)
1957 {
1958 const CairoColor *dark = &colors->shade[3];
1959 CairoColor hilight;
1960
1961 ge_shade_color (dark, 1.4, &hilight);
1962
1963 cairo_set_line_width (cr, 1);
1964 cairo_translate (cr, x, y+0.5);
1965 cairo_move_to (cr, 0, 0);
1966 cairo_line_to (cr, width, 0);
1967 ge_cairo_set_color (cr, dark);
1968 cairo_stroke (cr);
1969
1970 cairo_translate (cr, 0, 1);
1971 cairo_move_to (cr, 0, 0);
1972 cairo_line_to (cr, width, 0);
1973 ge_cairo_set_color (cr, &hilight);
1974 cairo_stroke (cr);
1975 }
1976
1977 static void
clearlooks_draw_menu_frame(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1978 clearlooks_draw_menu_frame (cairo_t *cr,
1979 const ClearlooksColors *colors,
1980 const WidgetParameters *widget,
1981 int x, int y, int width, int height)
1982 {
1983 const CairoColor *border = &colors->shade[5];
1984 cairo_translate (cr, x, y);
1985 cairo_set_line_width (cr, 1);
1986
1987 ge_cairo_set_color (cr, border);
1988 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1989 }
1990
1991 static void
clearlooks_draw_tooltip(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1992 clearlooks_draw_tooltip (cairo_t *cr,
1993 const ClearlooksColors *colors,
1994 const WidgetParameters *widget,
1995 int x, int y, int width, int height)
1996 {
1997 CairoColor border;
1998
1999 ge_shade_color (&colors->bg[widget->state_type], 0.6, &border);
2000
2001 cairo_save (cr);
2002
2003 cairo_translate (cr, x, y);
2004 cairo_set_line_width (cr, 1);
2005
2006 ge_cairo_set_color (cr, &colors->bg[widget->state_type]);
2007 cairo_rectangle (cr, 0, 0, width, height);
2008 cairo_fill (cr);
2009
2010 ge_cairo_set_color (cr, &border);
2011 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
2012
2013 cairo_restore (cr);
2014 }
2015
2016 static void
clearlooks_draw_icon_view_item(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)2017 clearlooks_draw_icon_view_item (cairo_t *cr,
2018 const ClearlooksColors *colors,
2019 const WidgetParameters *params,
2020 int x, int y, int width, int height)
2021 {
2022 CairoColor upper_color;
2023 CairoColor lower_color;
2024 cairo_pattern_t *pattern;
2025 cairo_save (cr);
2026
2027 cairo_translate (cr, x, y);
2028
2029 if (params->focus)
2030 upper_color = colors->base[params->state_type];
2031 else
2032 upper_color = colors->base[GTK_STATE_ACTIVE];
2033
2034 ge_shade_color(&upper_color, 0.92, &lower_color);
2035
2036 pattern = cairo_pattern_create_linear (0, 0, 0, height);
2037 cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r,
2038 upper_color.g,
2039 upper_color.b);
2040 cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r,
2041 lower_color.g,
2042 lower_color.b);
2043
2044 cairo_set_source (cr, pattern);
2045 ge_cairo_rounded_rectangle (cr, 0, 0, width, height, params->radius, CR_CORNER_ALL);
2046 cairo_fill (cr);
2047
2048 cairo_pattern_destroy (pattern);
2049
2050 cairo_restore (cr);
2051 }
2052
2053 static void
clearlooks_draw_handle(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const HandleParameters * handle,int x,int y,int width,int height)2054 clearlooks_draw_handle (cairo_t *cr,
2055 const ClearlooksColors *colors,
2056 const WidgetParameters *params,
2057 const HandleParameters *handle,
2058 int x, int y, int width, int height)
2059 {
2060 const CairoColor *fill = &colors->bg[params->state_type];
2061 int num_bars = 6; /* shut up gcc warnings */
2062
2063 cairo_save (cr);
2064
2065 switch (handle->type)
2066 {
2067 case CL_HANDLE_TOOLBAR:
2068 num_bars = 6;
2069 break;
2070 case CL_HANDLE_SPLITTER:
2071 num_bars = 16;
2072 break;
2073 }
2074
2075 if (params->prelight)
2076 {
2077 cairo_rectangle (cr, x, y, width, height);
2078 ge_cairo_set_color (cr, fill);
2079 cairo_fill (cr);
2080 }
2081
2082 cairo_translate (cr, x, y);
2083
2084 cairo_set_line_width (cr, 1);
2085
2086 if (handle->horizontal)
2087 {
2088 params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, num_bars, 2, 0.1);
2089 }
2090 else
2091 {
2092 params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, 2, num_bars, 0.1);
2093 }
2094
2095 cairo_restore (cr);
2096 }
2097
2098 static void
clearlooks_draw_resize_grip(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ResizeGripParameters * grip,int x,int y,int width,int height)2099 clearlooks_draw_resize_grip (cairo_t *cr,
2100 const ClearlooksColors *colors,
2101 const WidgetParameters *widget,
2102 const ResizeGripParameters *grip,
2103 int x, int y, int width, int height)
2104 {
2105 const CairoColor *dark = &colors->shade[4];
2106 CairoColor hilight;
2107 int lx, ly;
2108 int x_down;
2109 int y_down;
2110 int dots;
2111
2112 ge_shade_color (dark, 1.5, &hilight);
2113
2114 /* The number of dots fitting into the area. Just hardcoded to 4 right now. */
2115 /* dots = MIN (width - 2, height - 2) / 3; */
2116 dots = 4;
2117
2118 cairo_save (cr);
2119
2120 switch (grip->edge)
2121 {
2122 case CL_WINDOW_EDGE_NORTH_EAST:
2123 x_down = 0;
2124 y_down = 0;
2125 cairo_translate (cr, x + width - 3*dots + 2, y + 1);
2126 break;
2127 case CL_WINDOW_EDGE_SOUTH_EAST:
2128 x_down = 0;
2129 y_down = 1;
2130 cairo_translate (cr, x + width - 3*dots + 2, y + height - 3*dots + 2);
2131 break;
2132 case CL_WINDOW_EDGE_SOUTH_WEST:
2133 x_down = 1;
2134 y_down = 1;
2135 cairo_translate (cr, x + 1, y + height - 3*dots + 2);
2136 break;
2137 case CL_WINDOW_EDGE_NORTH_WEST:
2138 x_down = 1;
2139 y_down = 0;
2140 cairo_translate (cr, x + 1, y + 1);
2141 break;
2142 default:
2143 /* Not implemented. */
2144 return;
2145 }
2146
2147 for (lx = 0; lx < dots; lx++) /* horizontally */
2148 {
2149 for (ly = 0; ly <= lx; ly++) /* vertically */
2150 {
2151 int mx, my;
2152 mx = x_down * dots + (1 - x_down * 2) * lx - x_down;
2153 my = y_down * dots + (1 - y_down * 2) * ly - y_down;
2154
2155 ge_cairo_set_color (cr, &hilight);
2156 cairo_rectangle (cr, mx*3-1, my*3-1, 2, 2);
2157 cairo_fill (cr);
2158
2159 ge_cairo_set_color (cr, dark);
2160 cairo_rectangle (cr, mx*3-1, my*3-1, 1, 1);
2161 cairo_fill (cr);
2162 }
2163 }
2164
2165 cairo_restore (cr);
2166 }
2167
2168 static void
clearlooks_draw_radiobutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)2169 clearlooks_draw_radiobutton (cairo_t *cr,
2170 const ClearlooksColors *colors,
2171 const WidgetParameters *widget,
2172 const CheckboxParameters *checkbox,
2173 int x, int y, int width, int height)
2174 {
2175 const CairoColor *border;
2176 const CairoColor *dot;
2177 CairoColor shadow;
2178 CairoColor highlight;
2179 cairo_pattern_t *pt;
2180 gboolean inconsistent;
2181 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2182 gdouble w, h, cx, cy, radius;
2183
2184 w = (gdouble) width;
2185 h = (gdouble) height;
2186 cx = width / 2.0;
2187 cy = height / 2.0;
2188 radius = MIN (width, height) / 2.0;
2189
2190 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2191 draw_bullet |= inconsistent;
2192
2193 if (widget->disabled)
2194 {
2195 border = &colors->shade[5];
2196 dot = &colors->shade[6];
2197 }
2198 else
2199 {
2200 border = &colors->shade[6];
2201 dot = &colors->text[0];
2202 }
2203
2204 ge_shade_color (&widget->parentbg, 0.9, &shadow);
2205 ge_shade_color (&widget->parentbg, 1.1, &highlight);
2206
2207 pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0);
2208 cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g);
2209 cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5);
2210 cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5);
2211 cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b);
2212
2213 cairo_translate (cr, x, y);
2214
2215 cairo_set_line_width (cr, MAX (1.0, floor (radius/3)));
2216 cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2);
2217 cairo_set_source (cr, pt);
2218 cairo_stroke (cr);
2219 cairo_pattern_destroy (pt);
2220
2221 cairo_set_line_width (cr, MAX (1.0, floor (radius/6)));
2222
2223 cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2);
2224
2225 if (!widget->disabled)
2226 {
2227 ge_cairo_set_color (cr, &colors->base[0]);
2228 cairo_fill_preserve (cr);
2229 }
2230
2231 ge_cairo_set_color (cr, border);
2232 cairo_stroke (cr);
2233
2234 if (draw_bullet)
2235 {
2236 if (inconsistent)
2237 {
2238 gdouble line_width = floor (radius * 2 / 3);
2239
2240 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
2241 cairo_set_line_width (cr, line_width);
2242
2243 cairo_move_to (cr, ceil (cx - radius/3.0 - line_width) + line_width, ceil (cy - line_width) + line_width);
2244 cairo_line_to (cr, floor (cx + radius/3.0 + line_width) - line_width, ceil (cy - line_width) + line_width);
2245
2246 ge_cairo_set_color (cr, dot);
2247 cairo_stroke (cr);
2248 }
2249 else
2250 {
2251 cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2);
2252 ge_cairo_set_color (cr, dot);
2253 cairo_fill (cr);
2254
2255 cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2);
2256 cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
2257 cairo_fill (cr);
2258 }
2259 }
2260 }
2261
2262 static void
clearlooks_draw_checkbox(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)2263 clearlooks_draw_checkbox (cairo_t *cr,
2264 const ClearlooksColors *colors,
2265 const WidgetParameters *widget,
2266 const CheckboxParameters *checkbox,
2267 int x, int y, int width, int height)
2268 {
2269 const CairoColor *border;
2270 const CairoColor *dot;
2271 gboolean inconsistent = FALSE;
2272 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2273
2274 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2275 draw_bullet |= inconsistent;
2276
2277 if (widget->disabled)
2278 {
2279 border = &colors->shade[5];
2280 dot = &colors->shade[6];
2281 }
2282 else
2283 {
2284 border = &colors->shade[6];
2285 dot = &colors->text[GTK_STATE_NORMAL];
2286 }
2287
2288 cairo_translate (cr, x, y);
2289 cairo_set_line_width (cr, 1);
2290
2291 if (widget->xthickness >= 3 && widget->ythickness >= 3)
2292 {
2293 widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, width, height, 1, CR_CORNER_ALL);
2294
2295 /* Draw the rectangle for the checkbox itself */
2296 ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
2297 }
2298 else
2299 {
2300 /* Draw the rectangle for the checkbox itself */
2301 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
2302 }
2303
2304 if (!widget->disabled)
2305 {
2306 ge_cairo_set_color (cr, &colors->base[0]);
2307 cairo_fill_preserve (cr);
2308 }
2309
2310 ge_cairo_set_color (cr, border);
2311 cairo_stroke (cr);
2312
2313 if (draw_bullet)
2314 {
2315 if (inconsistent) /* Inconsistent */
2316 {
2317 cairo_set_line_width (cr, 2.0);
2318 cairo_move_to (cr, 3, height*0.5);
2319 cairo_line_to (cr, width-3, height*0.5);
2320 }
2321 else
2322 {
2323 cairo_set_line_width (cr, 1.7);
2324 cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5));
2325 cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7));
2326
2327 cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7),
2328 0.5 + (width*0.5), (height*0.4),
2329 0.5 + (width*0.70), (height*0.25));
2330
2331 }
2332
2333 ge_cairo_set_color (cr, dot);
2334 cairo_stroke (cr);
2335 }
2336 }
2337
2338 static void
clearlooks_draw_normal_arrow(cairo_t * cr,const CairoColor * color,double x,double y,double width,double height)2339 clearlooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color,
2340 double x, double y, double width, double height)
2341 {
2342 double arrow_width;
2343 double arrow_height;
2344 double line_width_2;
2345
2346 cairo_save (cr);
2347
2348 arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width);
2349 line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0;
2350 arrow_height = arrow_width / 2.0 + line_width_2;
2351
2352 cairo_translate (cr, x, y - arrow_height / 2.0);
2353
2354 cairo_move_to (cr, -arrow_width / 2.0, line_width_2);
2355 cairo_line_to (cr, -arrow_width / 2.0 + line_width_2, 0);
2356 /* cairo_line_to (cr, 0, arrow_height - line_width_2); */
2357 cairo_arc_negative (cr, 0, arrow_height - 2*line_width_2 - 2*line_width_2 * sqrt(2), 2*line_width_2, G_PI_2 + G_PI_4, G_PI_4);
2358 cairo_line_to (cr, arrow_width / 2.0 - line_width_2, 0);
2359 cairo_line_to (cr, arrow_width / 2.0, line_width_2);
2360 cairo_line_to (cr, 0, arrow_height);
2361 cairo_close_path (cr);
2362
2363 ge_cairo_set_color (cr, color);
2364 cairo_fill (cr);
2365
2366 cairo_restore (cr);
2367 }
2368
2369 static void
clearlooks_draw_combo_arrow(cairo_t * cr,const CairoColor * color,double x,double y,double width,double height)2370 clearlooks_draw_combo_arrow (cairo_t *cr, const CairoColor *color,
2371 double x, double y, double width, double height)
2372 {
2373 double arrow_width = MIN (height * 2 / 3.0, width);
2374 double arrow_height = arrow_width / 2.0;
2375 double gap_size = 1.0 * arrow_height;
2376
2377 cairo_save (cr);
2378 cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0);
2379 cairo_rotate (cr, G_PI);
2380 clearlooks_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
2381 cairo_restore (cr);
2382
2383 clearlooks_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height);
2384 }
2385
2386 static void
_clearlooks_draw_arrow(cairo_t * cr,const CairoColor * color,ClearlooksDirection dir,ClearlooksArrowType type,double x,double y,double width,double height)2387 _clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color,
2388 ClearlooksDirection dir, ClearlooksArrowType type,
2389 double x, double y, double width, double height)
2390 {
2391 double rotate;
2392
2393 if (dir == CL_DIRECTION_LEFT)
2394 rotate = G_PI*1.5;
2395 else if (dir == CL_DIRECTION_RIGHT)
2396 rotate = G_PI*0.5;
2397 else if (dir == CL_DIRECTION_UP)
2398 rotate = G_PI;
2399 else if (dir == CL_DIRECTION_DOWN)
2400 rotate = 0;
2401 else
2402 return;
2403
2404 if (type == CL_ARROW_NORMAL)
2405 {
2406 cairo_translate (cr, x, y);
2407 cairo_rotate (cr, -rotate);
2408 clearlooks_draw_normal_arrow (cr, color, 0, 0, width, height);
2409 }
2410 else if (type == CL_ARROW_COMBO)
2411 {
2412 cairo_translate (cr, x, y);
2413 clearlooks_draw_combo_arrow (cr, color, 0, 0, width, height);
2414 }
2415 }
2416
2417 static void
clearlooks_draw_arrow(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ArrowParameters * arrow,int x,int y,int width,int height)2418 clearlooks_draw_arrow (cairo_t *cr,
2419 const ClearlooksColors *colors,
2420 const WidgetParameters *widget,
2421 const ArrowParameters *arrow,
2422 int x, int y, int width, int height)
2423 {
2424 const CairoColor *color = &colors->fg[widget->state_type];
2425 gdouble tx, ty;
2426
2427 tx = x + width/2.0;
2428 ty = y + height/2.0;
2429
2430 if (widget->disabled)
2431 {
2432 _clearlooks_draw_arrow (cr, &colors->shade[0],
2433 arrow->direction, arrow->type,
2434 tx+0.5, ty+0.5, width, height);
2435 }
2436
2437 cairo_identity_matrix (cr);
2438
2439 _clearlooks_draw_arrow (cr, color, arrow->direction, arrow->type,
2440 tx, ty, width, height);
2441 }
2442
2443 void
clearlooks_draw_focus(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)2444 clearlooks_draw_focus (cairo_t *cr,
2445 const ClearlooksColors *colors,
2446 const WidgetParameters *widget,
2447 const FocusParameters *focus,
2448 int x, int y, int width, int height)
2449 {
2450 if (focus->has_color)
2451 ge_cairo_set_color (cr, &focus->color);
2452 else if (focus->type == CL_FOCUS_COLOR_WHEEL_LIGHT)
2453 cairo_set_source_rgb (cr, 0., 0., 0.);
2454 else if (focus->type == CL_FOCUS_COLOR_WHEEL_DARK)
2455 cairo_set_source_rgb (cr, 1., 1., 1.);
2456 else
2457 cairo_set_source_rgba (cr,
2458 colors->fg[widget->state_type].r,
2459 colors->fg[widget->state_type].g,
2460 colors->fg[widget->state_type].b,
2461 0.7);
2462
2463 cairo_set_line_width (cr, focus->line_width);
2464
2465 if (focus->dash_list[0])
2466 {
2467 gint n_dashes = strlen ((gchar *)focus->dash_list);
2468 gdouble *dashes = g_new (gdouble, n_dashes);
2469 gdouble total_length = 0;
2470 gdouble dash_offset;
2471 gint i;
2472
2473 for (i = 0; i < n_dashes; i++)
2474 {
2475 dashes[i] = focus->dash_list[i];
2476 total_length += focus->dash_list[i];
2477 }
2478
2479 dash_offset = -focus->line_width / 2.0;
2480 while (dash_offset < 0)
2481 dash_offset += total_length;
2482
2483 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
2484 g_free (dashes);
2485 }
2486
2487 cairo_rectangle (cr,
2488 x + focus->line_width / 2.0,
2489 y + focus->line_width / 2.0,
2490 width - focus->line_width, height - focus->line_width);
2491 cairo_stroke (cr);
2492 }
2493
2494 void
clearlooks_set_mixed_color(cairo_t * cr,const CairoColor * color1,const CairoColor * color2,gdouble mix_factor)2495 clearlooks_set_mixed_color (cairo_t *cr,
2496 const CairoColor *color1,
2497 const CairoColor *color2,
2498 gdouble mix_factor)
2499 {
2500 CairoColor composite;
2501
2502 ge_mix_color (color1, color2, mix_factor, &composite);
2503 ge_cairo_set_color (cr, &composite);
2504 }
2505
2506 void
clearlooks_register_style_classic(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)2507 clearlooks_register_style_classic (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
2508 {
2509 g_assert (functions);
2510
2511 functions->draw_top_left_highlight = clearlooks_draw_top_left_highlight;
2512 functions->draw_button = clearlooks_draw_button;
2513 functions->draw_scale_trough = clearlooks_draw_scale_trough;
2514 functions->draw_progressbar_trough = clearlooks_draw_progressbar_trough;
2515 functions->draw_progressbar_fill = clearlooks_draw_progressbar_fill;
2516 functions->draw_slider_button = clearlooks_draw_slider_button;
2517 functions->draw_entry = clearlooks_draw_entry;
2518 functions->draw_entry_progress = clearlooks_draw_entry_progress;
2519 functions->draw_spinbutton = clearlooks_draw_spinbutton;
2520 functions->draw_spinbutton_down = clearlooks_draw_spinbutton_down;
2521 functions->draw_optionmenu = clearlooks_draw_optionmenu;
2522 functions->draw_inset = clearlooks_draw_inset;
2523 functions->draw_menubar = clearlooks_draw_menubar;
2524 functions->draw_tab = clearlooks_draw_tab;
2525 functions->draw_frame = clearlooks_draw_frame;
2526 functions->draw_separator = clearlooks_draw_separator;
2527 functions->draw_menu_item_separator = clearlooks_draw_menu_item_separator;
2528 functions->draw_list_view_header = clearlooks_draw_list_view_header;
2529 functions->draw_toolbar = clearlooks_draw_toolbar;
2530 functions->draw_menuitem = clearlooks_draw_menuitem;
2531 functions->draw_menubaritem = clearlooks_draw_menubaritem;
2532 functions->draw_selected_cell = clearlooks_draw_selected_cell;
2533 functions->draw_scrollbar_stepper = clearlooks_draw_scrollbar_stepper;
2534 functions->draw_scrollbar_slider = clearlooks_draw_scrollbar_slider;
2535 functions->draw_scrollbar_trough = clearlooks_draw_scrollbar_trough;
2536 functions->draw_statusbar = clearlooks_draw_statusbar;
2537 functions->draw_menu_frame = clearlooks_draw_menu_frame;
2538 functions->draw_tooltip = clearlooks_draw_tooltip;
2539 functions->draw_icon_view_item = clearlooks_draw_icon_view_item;
2540 functions->draw_handle = clearlooks_draw_handle;
2541 functions->draw_resize_grip = clearlooks_draw_resize_grip;
2542 functions->draw_arrow = clearlooks_draw_arrow;
2543 functions->draw_focus = clearlooks_draw_focus;
2544 functions->draw_checkbox = clearlooks_draw_checkbox;
2545 functions->draw_radiobutton = clearlooks_draw_radiobutton;
2546 functions->draw_shadow = clearlooks_draw_shadow;
2547 functions->draw_slider = clearlooks_draw_slider;
2548 functions->draw_gripdots = clearlooks_draw_gripdots;
2549
2550 constants->topleft_highlight_shade = 1.3;
2551 constants->topleft_highlight_alpha = 0.6;
2552 }
2553