1 /* Murrine theme engine
2 * Copyright (C) 2006-2007-2008-2009 Andrea Cimitan
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #include <cairo.h>
22
23 #include "murrine_draw.h"
24 #include "murrine_style.h"
25 #include "murrine_types.h"
26 #include "support.h"
27 #include "cairo-support.h"
28 #include "raico-blur.h"
29
30 static void
murrine_draw_inset(cairo_t * cr,const MurrineRGB * bg_color,double x,double y,double w,double h,double radius,uint8 corners)31 murrine_draw_inset (cairo_t *cr,
32 const MurrineRGB *bg_color,
33 double x, double y, double w, double h,
34 double radius, uint8 corners)
35 {
36 MurrineRGB shadow, highlight;
37 radius = MIN (radius, MIN (w/2.0, h/2.0));
38
39 murrine_shade (bg_color, 0.74, &shadow);
40 murrine_shade (bg_color, 1.3, &highlight);
41
42 /* highlight */
43 cairo_move_to (cr, x+w+(radius*-0.2928932188), y-(radius*-0.2928932188));
44
45 if (corners & MRN_CORNER_TOPRIGHT)
46 cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.75, M_PI*2);
47 else
48 cairo_line_to (cr, x+w, y);
49
50 if (corners & MRN_CORNER_BOTTOMRIGHT)
51 cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI*0.5);
52 else
53 cairo_line_to (cr, x+w, y+h);
54
55 if (corners & MRN_CORNER_BOTTOMLEFT)
56 cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.5, M_PI*0.75);
57 else
58 cairo_line_to (cr, x, y+h);
59
60 murrine_set_color_rgba (cr, &highlight, 0.42);
61 cairo_stroke (cr);
62
63 /* shadow */
64 cairo_move_to (cr, x+(radius*0.2928932188), y+h+(radius*-0.2928932188));
65
66 if (corners & MRN_CORNER_BOTTOMLEFT)
67 cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.75, M_PI);
68 else
69 cairo_line_to (cr, x, y+h);
70
71 if (corners & MRN_CORNER_TOPLEFT)
72 cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
73 else
74 cairo_line_to (cr, x, y);
75
76 if (corners & MRN_CORNER_TOPRIGHT)
77 cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.5, M_PI*1.75);
78 else
79 cairo_line_to (cr, x+w, y);
80
81 murrine_set_color_rgba (cr, &shadow, 0.16);
82 cairo_stroke (cr);
83 }
84
85 static void
murrine_draw_highlight_and_shade(cairo_t * cr,const MurrineColors * colors,const ShadowParameters * widget,int width,int height,int radius)86 murrine_draw_highlight_and_shade (cairo_t *cr,
87 const MurrineColors *colors,
88 const ShadowParameters *widget,
89 int width, int height, int radius)
90 {
91 MurrineRGB highlight;
92 MurrineRGB shadow;
93 uint8 corners = widget->corners;
94 double x = 1.0;
95 double y = 1.0;
96 width -= 3;
97 height -= 3;
98 radius = MIN (radius, MIN ((double)width/2.0, (double)height/2.0));
99
100 if (radius < 0)
101 radius = 0;
102
103 murrine_shade (&colors->bg[0], 1.04, &highlight);
104 murrine_shade (&colors->bg[0], 0.96, &shadow);
105
106 cairo_save (cr);
107
108 /* Top/Left highlight */
109 if (corners & MRN_CORNER_BOTTOMLEFT)
110 cairo_move_to (cr, x, y+height-radius);
111 else
112 cairo_move_to (cr, x, y+height);
113
114 murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
115
116 if (corners & MRN_CORNER_TOPRIGHT)
117 cairo_line_to (cr, x+width-radius, y);
118 else
119 cairo_line_to (cr, x+width, y);
120
121 if (widget->shadow & MRN_SHADOW_OUT)
122 murrine_set_color_rgb (cr, &highlight);
123 else
124 murrine_set_color_rgb (cr, &shadow);
125
126 cairo_stroke (cr);
127
128 /* Bottom/Right highlight -- this includes the corners */
129 cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
130 murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
131 murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
132 murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
133
134 if (widget->shadow & MRN_SHADOW_OUT)
135 murrine_set_color_rgb (cr, &shadow);
136 else
137 murrine_set_color_rgb (cr, &highlight);
138
139 cairo_stroke (cr);
140
141 cairo_restore (cr);
142 }
143
144 static void
murrine_draw_button(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ButtonParameters * button,int x,int y,int width,int height,boolean horizontal)145 murrine_draw_button (cairo_t *cr,
146 const MurrineColors *colors,
147 const WidgetParameters *widget,
148 const ButtonParameters *button,
149 int x, int y, int width, int height,
150 boolean horizontal)
151 {
152 int os = (widget->xthickness > 2 && widget->ythickness > 2) ? 1 : 0;
153 double glow_shade_new = widget->glow_shade;
154 double highlight_shade_new = widget->highlight_shade;
155 double lightborder_shade_new = widget->lightborder_shade;
156 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
157 MurrineRGB border;
158 MurrineRGB fill = colors->bg[widget->state_type];
159 /*
160 if (widget->active)
161 {
162 mrn_gradient_new.has_border_colors = FALSE;
163 mrn_gradient_new.has_gradient_colors = FALSE;
164 }
165 */
166 murrine_get_fill_color (&fill, &mrn_gradient_new);
167
168 if (widget->disabled)
169 {
170 mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
171 mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
172 mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
173 glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
174 highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
175 lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
176 murrine_shade (&fill, murrine_get_contrast(0.75, widget->contrast), &border);
177 }
178 else
179 murrine_shade (&fill, murrine_get_contrast(0.475, widget->contrast), &border);
180
181 /* Default button */
182 if (widget->is_default && !widget->disabled)
183 {
184 murrine_shade (&border, murrine_get_contrast(0.8, widget->contrast), &border);
185
186 if (button->has_default_button_color)
187 {
188 mrn_gradient_new.has_border_colors = FALSE;
189 mrn_gradient_new.has_gradient_colors = FALSE;
190 murrine_mix_color (&fill, &button->default_button_color, 0.8, &fill);
191 }
192 else
193 murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
194
195 if (mrn_gradient_new.has_border_colors)
196 {
197 murrine_shade (&mrn_gradient_new.border_colors[0], 0.8, &mrn_gradient_new.border_colors[0]);
198 murrine_shade (&mrn_gradient_new.border_colors[1], 0.8, &mrn_gradient_new.border_colors[1]);
199 }
200 }
201
202 if (!horizontal)
203 murrine_exchange_axis (cr, &x, &y, &width, &height);
204
205 cairo_translate (cr, x, y);
206
207 if (!widget->active && !widget->disabled && widget->reliefstyle > 1 && os > 0)
208 {
209 if (widget->reliefstyle == 5)
210 murrine_draw_shadow (cr, &widget->parentbg,
211 0.5, 0.5, width-1, height-1,
212 widget->roundness+1, widget->corners,
213 widget->reliefstyle,
214 mrn_gradient_new, 0.5);
215 else
216 {
217 murrine_draw_shadow (cr, &border,
218 os-0.5, os-0.5, width-(os*2)+1, height-(os*2)+1,
219 widget->roundness+1, widget->corners,
220 widget->reliefstyle,
221 mrn_gradient_new, 0.08);
222 }
223 }
224 else if (widget->reliefstyle != 0 && os > 0)
225 {
226 mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
227 murrine_draw_inset (cr, &widget->parentbg, os-0.5, os-0.5,
228 width-(os*2)+1, height-(os*2)+1,
229 widget->roundness+1, widget->corners);
230 }
231
232 murrine_mix_color (&border, &fill, 0.4, &border);
233
234 cairo_save (cr);
235
236 murrine_rounded_rectangle_closed (cr, os+1, os+1, width-(os*2)-2, height-(os*2)-2, widget->roundness-1, widget->corners);
237 cairo_clip_preserve (cr);
238
239 murrine_draw_glaze (cr, &fill,
240 glow_shade_new, highlight_shade_new, !widget->active ? lightborder_shade_new : 1.0,
241 mrn_gradient_new, widget,
242 os+1, os+1, width-(os*2)-2, height-(os*2)-2,
243 widget->roundness-1, widget->corners, horizontal);
244
245 cairo_restore (cr);
246
247 /* Draw pressed button shadow */
248 if (widget->active)
249 {
250 cairo_pattern_t *pat;
251 MurrineRGB shadow;
252
253 murrine_shade (&fill, 0.94, &shadow);
254
255 cairo_save (cr);
256
257 murrine_rounded_rectangle_closed (cr, os+1, os+1, width-(os*2)-2, height-(os*2)-2, widget->roundness-1,
258 widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
259 cairo_clip (cr);
260
261 cairo_rectangle (cr, os+1, os+1, width-(os*2)-2, 3);
262 pat = cairo_pattern_create_linear (os+1, os+1, os+1, os+4);
263 murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.58);
264 murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
265 cairo_set_source (cr, pat);
266 cairo_fill (cr);
267 cairo_pattern_destroy (pat);
268
269 cairo_rectangle (cr, os+1, os+1, 3, height-(os*2)-2);
270 pat = cairo_pattern_create_linear (os+1, os+1, os+4, os+1);
271 murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.58);
272 murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
273 cairo_set_source (cr, pat);
274 cairo_fill (cr);
275 cairo_pattern_destroy (pat);
276
277 cairo_restore (cr);
278 }
279
280 murrine_draw_border (cr, &border,
281 os+0.5, os+0.5, width-(os*2)-1, height-(os*2)-1,
282 widget->roundness, widget->corners,
283 mrn_gradient_new, 1.0);
284 }
285
286 static void
murrine_draw_entry(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)287 murrine_draw_entry (cairo_t *cr,
288 const MurrineColors *colors,
289 const WidgetParameters *widget,
290 const FocusParameters *focus,
291 int x, int y, int width, int height)
292 {
293 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
294 const MurrineRGB *base = &colors->base[widget->state_type];
295 MurrineRGB border = colors->shade[widget->disabled ? 4 : 6];
296 int radius = CLAMP (widget->roundness, 0, 3);
297
298 if (widget->focus)
299 border = focus->color;
300
301 cairo_translate (cr, x+0.5, y+0.5);
302
303 /* Fill the entry's base color */
304 cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
305 murrine_set_color_rgb (cr, base);
306 cairo_fill (cr);
307
308 if (widget->reliefstyle != 0)
309 murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
310
311 /* Draw the focused border */
312 if (widget->focus)
313 {
314 MurrineRGB focus_shadow;
315 murrine_shade (&border, 1.54, &focus_shadow);
316
317 cairo_rectangle (cr, 2, 2, width-5, height-5);
318 murrine_set_color_rgba (cr, &focus_shadow, 0.5);
319 cairo_stroke(cr);
320 }
321 else if (widget->mrn_gradient.gradients)
322 {
323 MurrineRGB shadow;
324 murrine_shade (&border, 0.925, &shadow);
325
326 cairo_move_to (cr, 2, height-3);
327 cairo_line_to (cr, 2, 2);
328 cairo_line_to (cr, width-3, 2);
329
330 murrine_set_color_rgba (cr, &shadow, widget->disabled ? 0.05 : 0.15);
331 cairo_stroke (cr);
332 }
333
334 mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
335
336 /* Draw border */
337 murrine_draw_border (cr, &border,
338 1, 1, width-3, height-3,
339 radius, widget->corners,
340 mrn_gradient_new, 1.0);
341 }
342
343 static void
murrine_draw_entry_progress(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const EntryProgressParameters * progress,int x,int y,int width,int height)344 murrine_draw_entry_progress (cairo_t *cr,
345 const MurrineColors *colors,
346 const WidgetParameters *widget,
347 const EntryProgressParameters *progress,
348 int x, int y, int width, int height)
349 {
350 MurrineRGB border;
351 MurrineRGB fill;
352 gint entry_width, entry_height;
353 double entry_radius;
354 double radius;
355
356 cairo_save (cr);
357
358 fill = colors->bg[widget->state_type];
359 murrine_shade (&fill, 0.9, &border);
360
361 if (progress->max_size_known)
362 {
363 entry_width = progress->max_size.width+progress->border.left+progress->border.right;
364 entry_height = progress->max_size.height+progress->border.top+progress->border.bottom;
365 entry_radius = MIN (widget->roundness, MIN ((entry_width-4.0)/2.0, (entry_height-4.0)/2.0));
366 }
367 else
368 {
369 entry_radius = widget->roundness;
370 }
371
372 radius = MAX (0, entry_radius+1.0-MAX (MAX (progress->border.left, progress->border.right),
373 MAX (progress->border.top, progress->border.bottom)));
374
375 if (progress->max_size_known)
376 {
377 /* Clip to the max size, and then draw a (larger) rectangle ... */
378 clearlooks_rounded_rectangle (cr, progress->max_size.x,
379 progress->max_size.y,
380 progress->max_size.width,
381 progress->max_size.height,
382 radius,
383 MRN_CORNER_ALL);
384 cairo_clip (cr);
385
386 /* We just draw wider by one pixel ... */
387 murrine_set_color_rgb (cr, &fill);
388 cairo_rectangle (cr, x, y+1, width, height-2);
389 cairo_fill (cr);
390
391 cairo_set_line_width (cr, 1.0);
392 murrine_set_color_rgb (cr, &border);
393 cairo_rectangle (cr, x-0.5, y+0.5, width+1, height-1);
394 cairo_stroke (cr);
395 }
396 else
397 {
398 clearlooks_rounded_rectangle (cr, x, y, width+10, height+10, radius, MRN_CORNER_ALL);
399 cairo_clip (cr);
400 clearlooks_rounded_rectangle (cr, x-10, y-10, width+10, height+10, radius, MRN_CORNER_ALL);
401 cairo_clip (cr);
402
403 murrine_set_color_rgb (cr, &fill);
404 clearlooks_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, MRN_CORNER_ALL);
405 cairo_fill (cr);
406
407 cairo_set_line_width (cr, 1.0);
408 murrine_set_color_rgb (cr, &border);
409 clearlooks_rounded_rectangle (cr, x+0.5, y+0.5, width-1.0, height-1.0, radius, MRN_CORNER_ALL);
410 cairo_stroke (cr);
411 }
412
413 cairo_restore (cr);
414 }
415
416 static void
murrine_draw_spinbutton(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SpinbuttonParameters * spinbutton,int x,int y,int width,int height,boolean horizontal)417 murrine_draw_spinbutton (cairo_t *cr,
418 const MurrineColors *colors,
419 const WidgetParameters *widget,
420 const SpinbuttonParameters *spinbutton,
421 int x, int y, int width, int height,
422 boolean horizontal)
423 {
424 ButtonParameters button;
425 button.has_default_button_color = FALSE;
426
427 cairo_save (cr);
428
429 widget->style_functions->draw_button (cr, colors, widget, &button, x, y, width, height, horizontal);
430
431 cairo_restore (cr);
432
433 switch (spinbutton->style)
434 {
435 default:
436 case 0:
437 break;
438 case 1:
439 {
440 MurrineRGB line = colors->shade[!widget->disabled ? 6 : 5];
441 MurrineRGB highlight = colors->bg[widget->state_type];
442 double lightborder_shade_new = widget->lightborder_shade;
443 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
444
445 if (widget->disabled)
446 {
447 mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
448 lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
449 mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
450 mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
451 }
452 else
453 murrine_shade (&colors->shade[6], 0.95, &line);
454
455 /* adjust line accordingly to buttons */
456 if (widget->mrn_gradient.has_border_colors)
457 murrine_mix_color (&mrn_gradient_new.border_colors[0], &mrn_gradient_new.border_colors[1], 0.5, &line);
458 else if (widget->mrn_gradient.has_gradient_colors)
459 murrine_mix_color (&line, &mrn_gradient_new.gradient_colors[2], 0.4, &line);
460 else
461 murrine_mix_color (&line, &colors->bg[widget->state_type], 0.4, &line);
462 murrine_shade (&line, (mrn_gradient_new.border_shades[0]+mrn_gradient_new.border_shades[1])/2.0, &line);
463
464 /* adjust highlight accordingly to buttons */
465 if (widget->mrn_gradient.has_gradient_colors)
466 murrine_shade (&mrn_gradient_new.gradient_colors[2], mrn_gradient_new.gradient_shades[2], &highlight);
467 murrine_shade (&highlight, lightborder_shade_new*mrn_gradient_new.gradient_shades[2], &highlight);
468
469 /* this will align the path to the cairo grid */
470 if (height % 2 != 0)
471 height++;
472
473 cairo_move_to (cr, x+2, y+height/2.0-0.5);
474 cairo_line_to (cr, width-3, y+height/2.0-0.5);
475 murrine_set_color_rgb (cr, &line);
476 cairo_stroke (cr);
477
478 cairo_move_to (cr, x+3, y+height/2.0+0.5);
479 cairo_line_to (cr, width-4, y+height/2.0+0.5);
480 murrine_set_color_rgba (cr, &highlight, 0.5);
481 cairo_stroke (cr);
482 break;
483 }
484 }
485 }
486
487 static void
murrine_draw_spinbutton_down(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)488 murrine_draw_spinbutton_down (cairo_t *cr,
489 const MurrineColors *colors,
490 const WidgetParameters *widget,
491 int x, int y, int width, int height)
492 {
493 cairo_pattern_t *pat;
494 MurrineRGB shadow;
495 murrine_shade (&colors->bg[0], 0.8, &shadow);
496
497 cairo_translate (cr, x+1, y+1);
498
499 cairo_rectangle (cr, 1, 1, width-4, height-4);
500 pat = cairo_pattern_create_linear (0, 0, 0, height);
501 murrine_pattern_add_color_stop_rgb (pat, 0.0, &shadow);
502 murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
503 cairo_set_source (cr, pat);
504 cairo_fill (cr);
505 cairo_pattern_destroy (pat);
506 }
507
508 static void
murrine_scale_draw_gradient(cairo_t * cr,const MurrineRGB * c1,const MurrineRGB * c2,double lightborder_shade,int lightborderstyle,int roundness,uint8 corners,int x,int y,int width,int height,boolean horizontal)509 murrine_scale_draw_gradient (cairo_t *cr,
510 const MurrineRGB *c1,
511 const MurrineRGB *c2,
512 double lightborder_shade,
513 int lightborderstyle,
514 int roundness, uint8 corners,
515 int x, int y, int width, int height,
516 boolean horizontal)
517 {
518 murrine_set_color_rgb (cr, c1);
519 murrine_rounded_rectangle_closed (cr, x, y, width, height, roundness, corners);
520 cairo_fill (cr);
521
522 if (lightborder_shade != 1.0)
523 {
524 cairo_pattern_t *pat;
525 double fill_pos = horizontal ? 1.0-1.0/(double)(height-2) :
526 1.0-1.0/(double)(width-2);
527 MurrineRGB lightborder;
528 murrine_shade (c1, lightborder_shade, &lightborder);
529
530 roundness < 2 ? cairo_rectangle (cr, x, y, width, height) :
531 clearlooks_rounded_rectangle (cr, x+1, y+1, width-2, height-2, roundness-1, corners);
532 pat = cairo_pattern_create_linear (x+1, y+1, horizontal ? x+1 : width+x+1, horizontal ? height+y+1 : y+1);
533
534 murrine_pattern_add_color_stop_rgba (pat, 0.00, &lightborder, 0.75);
535 murrine_pattern_add_color_stop_rgba (pat, fill_pos, &lightborder, 0.75);
536 murrine_pattern_add_color_stop_rgba (pat, fill_pos, &lightborder, 0.0);
537 murrine_pattern_add_color_stop_rgba (pat, 1.00, &lightborder, 0.0);
538
539 cairo_set_source (cr, pat);
540 cairo_pattern_destroy (pat);
541
542 cairo_stroke (cr);
543 }
544
545 murrine_set_color_rgb (cr, c2);
546 murrine_rounded_rectangle (cr, x, y, width, height, roundness, corners);
547 cairo_stroke (cr);
548 }
549
550 static void
murrine_scale_draw_trough(cairo_t * cr,const MurrineRGB * c1,const MurrineRGB * c2,MurrineGradients mrn_gradient,int roundness,uint8 corners,int x,int y,int width,int height,boolean horizontal)551 murrine_scale_draw_trough (cairo_t *cr,
552 const MurrineRGB *c1,
553 const MurrineRGB *c2,
554 MurrineGradients mrn_gradient,
555 int roundness, uint8 corners,
556 int x, int y, int width, int height,
557 boolean horizontal)
558 {
559 murrine_draw_trough (cr, c1, x, y, width, height, roundness, corners, mrn_gradient, 1.0, horizontal);
560 murrine_draw_trough_border (cr, c2, x, y, width, height, roundness, corners, mrn_gradient, 1.0, horizontal);
561 }
562
563 #define TROUGH_SIZE 6
564 static void
murrine_draw_scale_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SliderParameters * slider,int x,int y,int width,int height)565 murrine_draw_scale_trough (cairo_t *cr,
566 const MurrineColors *colors,
567 const WidgetParameters *widget,
568 const SliderParameters *slider,
569 int x, int y, int width, int height)
570 {
571 int trough_width, trough_height;
572 double translate_x, translate_y;
573
574 cairo_save (cr);
575
576 if (slider->horizontal)
577 {
578 trough_width = width;
579 trough_height = TROUGH_SIZE;
580
581 translate_x = x;
582 translate_y = y+(height/2)-(TROUGH_SIZE/2);
583 }
584 else
585 {
586 trough_width = TROUGH_SIZE;
587 trough_height = height;
588
589 translate_x = x+(width/2)-(TROUGH_SIZE/2);
590 translate_y = y;
591 }
592
593 cairo_translate (cr, translate_x+0.5, translate_y+0.5);
594
595 if (!slider->fill_level && widget->reliefstyle != 0)
596 murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width, trough_height, widget->roundness, widget->corners);
597
598 if (!slider->lower && !slider->fill_level)
599 {
600 MurrineRGB fill, border;
601 murrine_shade (&colors->bg[GTK_STATE_ACTIVE], 1.0, &fill);
602 murrine_shade (&colors->bg[GTK_STATE_ACTIVE], murrine_get_contrast(0.82, widget->contrast), &border);
603
604 murrine_scale_draw_trough (cr, &fill, &border, widget->mrn_gradient,
605 widget->roundness, widget->corners,
606 1.0, 1.0, trough_width-2, trough_height-2,
607 slider->horizontal);
608 }
609 else
610 {
611 MurrineRGB fill, border;
612 murrine_mix_color (&colors->bg[GTK_STATE_SELECTED], &widget->parentbg, widget->disabled ? 0.25 : 0.0, &fill);
613 murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &border);
614
615 murrine_scale_draw_gradient (cr, &fill, &border,
616 widget->disabled ? 1.0 : widget->lightborder_shade,
617 widget->lightborderstyle,
618 widget->roundness, widget->corners,
619 1.0, 1.0, trough_width-2, trough_height-2,
620 slider->horizontal);
621 }
622
623 cairo_restore (cr);
624 }
625
626 static void
murrine_draw_slider_path(cairo_t * cr,int x,int y,int width,int height,int roundness)627 murrine_draw_slider_path (cairo_t *cr,
628 int x, int y, int width, int height,
629 int roundness)
630 {
631 int radius = MIN (roundness, MIN (width/2.0, height/2.0));
632
633 cairo_move_to (cr, x+radius, y);
634 cairo_arc (cr, x+width-radius, y+radius, radius, M_PI*1.5, M_PI*2);
635 cairo_line_to (cr, x+width, y+height-width/2.0);
636 cairo_line_to (cr, x+width/2.0, y+height);
637 cairo_line_to (cr, x, y+height-width/2.0);
638 cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
639 }
640
641 static void
murrine_draw_slider(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SliderParameters * slider,int x,int y,int width,int height)642 murrine_draw_slider (cairo_t *cr,
643 const MurrineColors *colors,
644 const WidgetParameters *widget,
645 const SliderParameters *slider,
646 int x, int y, int width, int height)
647 {
648 int os = (widget->xthickness > 2 && widget->ythickness > 2) ? 1 : 0;
649 double glow_shade_new = widget->glow_shade;
650 double highlight_shade_new = widget->highlight_shade;
651 double lightborder_shade_new = widget->lightborder_shade;
652 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
653 MurrineRGB border;
654 MurrineRGB fill = colors->bg[widget->state_type];
655
656 murrine_get_fill_color (&fill, &mrn_gradient_new);
657
658 if (widget->disabled)
659 {
660 mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
661 mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
662 mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
663 glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
664 highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
665 lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
666 murrine_shade (&fill, murrine_get_contrast(0.75, widget->contrast), &border);
667 }
668 else
669 murrine_shade (&fill, murrine_get_contrast(0.475, widget->contrast), &border);
670
671 if (!slider->horizontal)
672 murrine_exchange_axis (cr, &x, &y, &width, &height);
673
674 cairo_save (cr);
675
676 cairo_translate (cr, x+0.5, y+0.5);
677
678 if (!widget->active && !widget->disabled && widget->reliefstyle > 1 && os > 0)
679 {
680 murrine_draw_slider_path (cr, os-1, os, width-(os*2)+2, height-(os*2)+1, widget->roundness+1);
681 if (widget->reliefstyle == 5)
682 murrine_draw_shadow_from_path (cr, &widget->parentbg,
683 os-1, os, width-(os*2)+2, height-(os*2)+1,
684 widget->reliefstyle,
685 mrn_gradient_new, 0.5);
686 else
687 murrine_draw_shadow_from_path (cr, &border,
688 os-1, os, width-(os*2)+2, height-(os*2)+1,
689 widget->reliefstyle,
690 mrn_gradient_new, 0.08);
691 }
692
693 murrine_mix_color (&border, &fill, 0.2, &border);
694
695 cairo_save (cr);
696
697 murrine_draw_slider_path (cr, os, os+1, width-(os*2), height-(os*2)-1, widget->roundness);
698 cairo_clip_preserve (cr);
699
700 murrine_draw_glaze (cr, &fill,
701 glow_shade_new, highlight_shade_new, !widget->active ? lightborder_shade_new : 1.0,
702 mrn_gradient_new, widget,
703 os, os+1, width-(os*2), height-(os*2)-1,
704 widget->roundness, widget->corners, TRUE);
705
706 cairo_restore (cr);
707
708 murrine_draw_slider_path (cr, os, os+1, width-(os*2), height-(os*2)-1, widget->roundness);
709
710 murrine_draw_border_from_path (cr, &border,
711 os, os+1, width-(os*2), height-(os*2)-1,
712 mrn_gradient_new, 1.0);
713
714 cairo_restore (cr);
715
716 if (!slider->horizontal)
717 murrine_exchange_axis (cr, &x, &y, &width, &height);
718 }
719
720
721 static void
murrine_draw_slider_handle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const HandleParameters * handle,int x,int y,int width,int height,boolean horizontal)722 murrine_draw_slider_handle (cairo_t *cr,
723 const MurrineColors *colors,
724 const WidgetParameters *widget,
725 const HandleParameters *handle,
726 int x, int y, int width, int height,
727 boolean horizontal)
728 {
729 int num_handles = 2, bar_x, i;
730 MurrineRGB color, inset;
731 murrine_shade (&colors->shade[6], 0.95, &color);
732
733 murrine_mix_color (&color, &colors->bg[widget->state_type], 0.4, &color);
734
735 if (!horizontal)
736 {
737 rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
738 int tmp = height; height = width; width = tmp;
739 }
740
741 if (width % 2 != 0)
742 num_handles = 3;
743 bar_x = width/2 - num_handles;
744
745 cairo_translate (cr, 0.5, 0.5);
746
747 switch (handle->style)
748 {
749 default:
750 case 0:
751 {
752 for (i=0; i<num_handles; i++)
753 {
754 cairo_move_to (cr, bar_x, 4.5);
755 cairo_line_to (cr, bar_x, height-5.5);
756 murrine_set_color_rgb (cr, &color);
757 cairo_stroke (cr);
758
759 bar_x += 3;
760 }
761 break;
762 }
763 case 1:
764 {
765 murrine_shade (&colors->bg[widget->state_type], 1.08, &inset);
766
767 for (i=0; i<num_handles; i++)
768 {
769 cairo_move_to (cr, bar_x, 4.5);
770 cairo_line_to (cr, bar_x, height-5.5);
771 murrine_set_color_rgb (cr, &color);
772 cairo_stroke (cr);
773
774 cairo_move_to (cr, bar_x+1, 4.5);
775 cairo_line_to (cr, bar_x+1, height-5.5);
776 murrine_set_color_rgb (cr, &inset);
777 cairo_stroke (cr);
778
779 bar_x += 3;
780 }
781 break;
782 }
783 case 2:
784 {
785 murrine_shade (&colors->bg[widget->state_type], 1.04, &inset);
786
787 bar_x++;
788
789 for (i=0; i<num_handles; i++)
790 {
791 cairo_move_to (cr, bar_x, 4.5);
792 cairo_line_to (cr, bar_x, height-5.5);
793 murrine_set_color_rgb (cr, &color);
794 cairo_stroke (cr);
795
796 cairo_move_to (cr, bar_x+1, 4.5);
797 cairo_line_to (cr, bar_x+1, height-5.5);
798 murrine_set_color_rgb (cr, &inset);
799 cairo_stroke (cr);
800
801 bar_x += 2;
802 }
803 break;
804 }
805 }
806 }
807
808 static void
murrine_draw_progressbar_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ProgressBarParameters * progressbar,int x,int y,int width,int height)809 murrine_draw_progressbar_trough (cairo_t *cr,
810 const MurrineColors *colors,
811 const WidgetParameters *widget,
812 const ProgressBarParameters *progressbar,
813 int x, int y, int width, int height)
814 {
815 MurrineRGB border, fill;
816 int roundness = MIN (widget->roundness, MIN ((height-2.0)/2.0, (width-2.0)/2.0));
817 boolean horizontal = progressbar->orientation < 2;
818
819 murrine_shade (&colors->bg[GTK_STATE_ACTIVE], 1.0, &fill);
820 murrine_shade (&colors->bg[GTK_STATE_ACTIVE], murrine_get_contrast(0.82, widget->contrast), &border);
821
822 /* Create trough box */
823 murrine_draw_trough (cr, &fill, x+1, y+1, width-2, height-2, roundness-1, widget->corners, widget->mrn_gradient, 1.0, horizontal);
824
825 /* Draw border */
826 murrine_draw_trough_border (cr, &border, x+0.5, y+0.5, width-1, height-1, roundness, widget->corners, widget->mrn_gradient, 1.0, horizontal);
827
828 if (widget->mrn_gradient.gradients &&
829 widget->mrn_gradient.trough_shades[0] == 1.0 &&
830 widget->mrn_gradient.trough_shades[1] == 1.0)
831 {
832 cairo_pattern_t *pat;
833 MurrineRGB shadow;
834
835 murrine_shade (&border, 0.94, &shadow);
836
837 /* clip the corners of the shadows */
838 murrine_rounded_rectangle_closed (cr, x+1, y+1, width-2, height-2, roundness, widget->corners);
839 cairo_clip (cr);
840
841 /* Top shadow */
842 cairo_rectangle (cr, x+1, y+1, width-2, 4);
843 pat = cairo_pattern_create_linear (x, y, x, y+4);
844 murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.24);
845 murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.);
846 cairo_set_source (cr, pat);
847 cairo_fill (cr);
848 cairo_pattern_destroy (pat);
849
850 /* Left shadow */
851 cairo_rectangle (cr, x+1, y+1, 4, height-2);
852 pat = cairo_pattern_create_linear (x, y, x+4, y);
853 murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.24);
854 murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.);
855 cairo_set_source (cr, pat);
856 cairo_fill (cr);
857 cairo_pattern_destroy (pat);
858 }
859 }
860
861 static void
murrine_draw_progressbar_fill(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ProgressBarParameters * progressbar,int x,int y,int width,int height,gint offset)862 murrine_draw_progressbar_fill (cairo_t *cr,
863 const MurrineColors *colors,
864 const WidgetParameters *widget,
865 const ProgressBarParameters *progressbar,
866 int x, int y, int width, int height,
867 gint offset)
868 {
869 double tile_pos = 0;
870 double stroke_width;
871 int x_step;
872 int roundness;
873 MurrineRGB border = colors->spot[2];
874 MurrineRGB effect;
875 MurrineRGB fill = colors->spot[1];
876
877 murrine_get_fill_color (&fill, &widget->mrn_gradient);
878 murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &effect);
879
880 /* progressbar->orientation < 2 == boolean is_horizontal */
881 if (progressbar->orientation < 2)
882 {
883 if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
884 rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
885 else
886 rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
887 }
888 else
889 {
890 int tmp = height; height = width; width = tmp;
891
892 x = x+1; y = y-1; width = width+2; height = height-2;
893
894 if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
895 rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
896 else
897 rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
898 }
899
900 roundness = MIN (widget->roundness-widget->xthickness, height/2.0);
901 int yos = 0;
902 if ((2*roundness > width) && roundness > 0)
903 {
904 int h = height*sin((M_PI*(width))/(4*roundness));
905 roundness = round(width/2.0);
906 yos = 0.5+(height-h)/2.0;
907 height = h;
908 }
909 stroke_width = height*2;
910 x_step = (((float)stroke_width/10)*offset);
911
912 cairo_save (cr);
913
914 murrine_rounded_rectangle_closed (cr, 2, 1+yos, width-4, height-2, roundness-1, widget->corners);
915 cairo_clip (cr);
916
917 cairo_rectangle (cr, 2, 1+yos, width-4, height-2);
918
919 murrine_draw_glaze (cr, &fill,
920 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
921 widget->mrn_gradient, widget, 2, 1+yos, width-4, height-2,
922 roundness, widget->corners, TRUE);
923
924 switch (progressbar->style)
925 {
926 case 0:
927 break;
928 default:
929 case 1:
930 {
931 /* Draw strokes */
932 while (stroke_width > 0 && tile_pos <= width+x_step)
933 {
934 cairo_move_to (cr, stroke_width/2-x_step, 0);
935 cairo_line_to (cr, stroke_width-x_step, 0);
936 cairo_line_to (cr, stroke_width/2-x_step, height);
937 cairo_line_to (cr, -x_step, height);
938
939 cairo_translate (cr, stroke_width, 0);
940 tile_pos += stroke_width;
941 }
942
943 murrine_set_color_rgba (cr, &effect, 0.15);
944 cairo_fill (cr);
945 break;
946 }
947 case 2:
948 {
949 MurrineRGB highlight;
950 int step = 18;
951 int i;
952
953 murrine_shade (&fill, widget->lightborder_shade*widget->highlight_shade, &highlight);
954
955 for (i=step; i<width-3; i+=step)
956 {
957 cairo_move_to (cr, i-0.5, 1);
958 cairo_line_to (cr, i-0.5, height-1);
959 murrine_set_color_rgba (cr, &highlight, 0.5);
960 cairo_stroke (cr);
961
962 cairo_move_to (cr, i+0.5, 1);
963 cairo_line_to (cr, i+0.5, height-1);
964 murrine_set_color_rgba (cr, &effect, 0.25);
965 cairo_stroke (cr);
966 }
967 break;
968 }
969 }
970
971 cairo_restore (cr);
972
973 cairo_save (cr);
974
975 murrine_rounded_rectangle_closed (cr, 0.5, -0.5+yos, width-1, height+1, roundness-1, widget->corners);
976 cairo_clip (cr);
977
978 /* Draw border */
979 murrine_mix_color (&border, &fill, 0.28, &border);
980 murrine_draw_border (cr, &border,
981 1.5, 0.5+yos, width-3, height-1,
982 roundness, widget->corners,
983 widget->mrn_gradient, 1.0);
984
985 cairo_restore (cr);
986 }
987
988 static void
murrine_draw_combobox(cairo_t * cr,MurrineColors colors,WidgetParameters widget,const ComboBoxParameters * combobox,int x,int y,int w,int h,boolean horizontal)989 murrine_draw_combobox (cairo_t *cr,
990 MurrineColors colors,
991 WidgetParameters widget,
992 const ComboBoxParameters *combobox,
993 int x, int y, int w, int h, boolean horizontal)
994 {
995 switch (combobox->style)
996 {
997 default:
998 case 0:
999 {
1000 ButtonParameters button;
1001 button.has_default_button_color = FALSE;
1002
1003 widget.style_functions->draw_button (cr, &colors, &widget, &button, x, y, w, h, horizontal);
1004 break;
1005 }
1006 case 1:
1007 {
1008 WidgetParameters params = widget;
1009 MurrineColors colors_new = colors;
1010 ButtonParameters button;
1011 button.has_default_button_color = FALSE;
1012 int box_w = (widget.xthickness > 2 && widget.ythickness > 2) ? combobox->box_w : combobox->box_w-3;
1013 int os = (widget.xthickness > 2 && widget.ythickness > 2) ? 1 : 0;
1014 colors_new.bg[GTK_STATE_NORMAL] = colors.spot[1];
1015 murrine_shade (&colors_new.bg[GTK_STATE_NORMAL], combobox->prelight_shade,
1016 &colors_new.bg[GTK_STATE_PRELIGHT]);
1017
1018 if (combobox->as_list)
1019 {
1020 params.style_functions->draw_button (cr, &colors_new, ¶ms, &button, x, y, w, h, horizontal);
1021 break;
1022 }
1023
1024 cairo_save (cr);
1025 if (params.ltr)
1026 {
1027 params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
1028 cairo_rectangle (cr, x, y, w-box_w, h);
1029 cairo_clip (cr);
1030 params.style_functions->draw_button (cr, &colors, ¶ms, &button, x, y, w-box_w+1+os, h, horizontal);
1031 }
1032 else
1033 {
1034 params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
1035 cairo_rectangle (cr, x+box_w, y, w-box_w, h);
1036 cairo_clip (cr);
1037 params.style_functions->draw_button (cr, &colors, ¶ms, &button, x+box_w-1-os, y, w-box_w+1+os, h, horizontal);
1038 }
1039 cairo_restore (cr);
1040
1041 params.mrn_gradient.has_border_colors = FALSE;
1042 params.mrn_gradient.has_gradient_colors = FALSE;
1043
1044 cairo_save (cr);
1045 if (params.ltr)
1046 {
1047 params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
1048 cairo_rectangle (cr, x+w-box_w, y, box_w, h);
1049 cairo_clip (cr);
1050 params.style_functions->draw_button (cr, &colors_new, ¶ms, &button, x+w-(box_w+os), y, box_w+os, h, horizontal);
1051 }
1052 else
1053 {
1054 params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
1055 cairo_rectangle (cr, x, y, box_w, h);
1056 cairo_clip (cr);
1057 params.style_functions->draw_button (cr, &colors_new, ¶ms, &button, x, y, box_w+os, h, horizontal);
1058 }
1059 cairo_restore (cr);
1060 break;
1061 }
1062 }
1063 }
1064
1065 static void
murrine_draw_optionmenu(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const OptionMenuParameters * optionmenu,int x,int y,int width,int height)1066 murrine_draw_optionmenu (cairo_t *cr,
1067 const MurrineColors *colors,
1068 const WidgetParameters *widget,
1069 const OptionMenuParameters *optionmenu,
1070 int x, int y, int width, int height)
1071 {
1072 ButtonParameters button;
1073 button.has_default_button_color = FALSE;
1074 int offset = widget->ythickness + 1;
1075
1076 boolean horizontal = TRUE;
1077 if (((float)width/height<0.5) || (widget->glazestyle > 0 && width<height))
1078 horizontal = FALSE;
1079
1080 widget->style_functions->draw_button (cr, colors, widget, &button, x, y, width, height, horizontal);
1081
1082 /* Draw the separator */
1083 MurrineRGB *dark = (MurrineRGB*)&colors->shade[6];
1084
1085 cairo_translate (cr, optionmenu->linepos+0.5, 1);
1086
1087 murrine_set_color_rgba (cr, dark, 0.4);
1088 cairo_move_to (cr, 0.0, offset);
1089 cairo_line_to (cr, 0.0, height - offset - widget->ythickness + 1);
1090 cairo_stroke (cr);
1091 }
1092
1093 static void
murrine_draw_menubar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menubarstyle)1094 murrine_draw_menubar (cairo_t *cr,
1095 const MurrineColors *colors,
1096 const WidgetParameters *widget,
1097 int x, int y, int width, int height,
1098 int menubarstyle)
1099 {
1100 const MurrineRGB *fill = &colors->bg[0];
1101 MurrineRGB dark = colors->shade[3];
1102
1103 if(widget->mrn_gradient.has_border_colors)
1104 dark = widget->mrn_gradient.border_colors[1];
1105
1106 cairo_translate (cr, x, y);
1107 cairo_rectangle (cr, 0, 0, width, height);
1108
1109 switch (menubarstyle)
1110 {
1111 default:
1112 case 0:
1113 murrine_set_color_rgb (cr, fill);
1114 cairo_fill (cr);
1115 break;
1116 case 1:
1117 {
1118 int os = (widget->glazestyle == 2) ? 1 : 0;
1119 murrine_draw_glaze (cr, fill,
1120 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1121 widget->mrn_gradient, widget, os, os, width-os*2, height-os*2,
1122 widget->roundness, widget->corners, TRUE);
1123 break;
1124 }
1125 case 2:
1126 {
1127 cairo_pattern_t *pat;
1128 double alpha = !widget->mrn_gradient.use_rgba ? 1.0 : 0.7;
1129 MurrineRGB lower;
1130 murrine_shade (fill, 0.95, &lower);
1131
1132 pat = cairo_pattern_create_linear (0, 0, 0, height);
1133 murrine_pattern_add_color_stop_rgba (pat, 0.0, fill, alpha);
1134 murrine_pattern_add_color_stop_rgba (pat, 1.0, &lower, alpha);
1135 cairo_set_source (cr, pat);
1136 cairo_fill (cr);
1137 cairo_pattern_destroy (pat);
1138 break;
1139 }
1140 case 3:
1141 {
1142 cairo_pattern_t *pat;
1143 int counter = -height;
1144 MurrineRGB low, top;
1145 murrine_shade (fill, 0.9, &top);
1146 murrine_shade (fill, 1.1, &low);
1147
1148 pat = cairo_pattern_create_linear (0, 0, 0, height);
1149 murrine_pattern_add_color_stop_rgb (pat, 0.0, &top);
1150 murrine_pattern_add_color_stop_rgb (pat, 1.0, &low);
1151 cairo_set_source (cr, pat);
1152 cairo_fill (cr);
1153 cairo_pattern_destroy (pat);
1154
1155 murrine_shade (&low, 0.9, &low);
1156 murrine_set_color_rgb (cr, &low);
1157 while (counter < width)
1158 {
1159 cairo_move_to (cr, counter, height);
1160 cairo_line_to (cr, counter+height, 0);
1161 cairo_stroke (cr);
1162 counter += 5;
1163 }
1164 break;
1165 }
1166 }
1167
1168 /* Draw bottom line */
1169 if (menubarstyle == 1 && widget->glazestyle == 2)
1170 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1171 else
1172 {
1173 cairo_move_to (cr, 0, height-0.5);
1174 cairo_line_to (cr, width, height-0.5);
1175 }
1176 murrine_set_color_rgb (cr, &dark);
1177 cairo_stroke (cr);
1178 }
1179
1180 /* We can't draw transparent things here, since it will be called on the same
1181 * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
1182 static void
murrine_draw_toolbar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1183 murrine_draw_toolbar (cairo_t *cr,
1184 const MurrineColors *colors,
1185 const WidgetParameters *widget,
1186 const ToolbarParameters *toolbar,
1187 int x, int y, int width, int height)
1188 {
1189 const MurrineRGB *fill = &colors->bg[0];
1190 const MurrineRGB *top = &colors->shade[0];
1191 MurrineRGB dark = colors->shade[3];
1192
1193 if(widget->mrn_gradient.has_border_colors)
1194 dark = widget->mrn_gradient.border_colors[1];
1195
1196 cairo_translate (cr, x, y);
1197 cairo_rectangle (cr, 0, 0, width, height);
1198
1199 /* Glass toolbar */
1200 switch (toolbar->style)
1201 {
1202 default:
1203 case 0:
1204 murrine_set_color_rgb (cr, fill);
1205 cairo_fill (cr);
1206
1207 /* Draw highlight */
1208 if (!toolbar->topmost)
1209 {
1210 cairo_move_to (cr, 0, 0.5);
1211 cairo_line_to (cr, width, 0.5);
1212 murrine_set_color_rgb (cr, top);
1213 cairo_stroke (cr);
1214 }
1215 break;
1216 case 1:
1217 {
1218 int os = (widget->glazestyle == 2) ? 1 : 0;
1219 murrine_draw_glaze (cr, fill,
1220 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1221 widget->mrn_gradient, widget, os, os, width-os*2, height-os*2,
1222 widget->roundness, widget->corners, TRUE);
1223 break;
1224 }
1225 case 2:
1226 {
1227 cairo_pattern_t *pat;
1228 MurrineRGB lower;
1229 murrine_shade (fill, 0.95, &lower);
1230 pat = cairo_pattern_create_linear (0, 0, 0, height);
1231 murrine_pattern_add_color_stop_rgb (pat, 0.0, fill);
1232 murrine_pattern_add_color_stop_rgb (pat, 1.0, &lower);
1233 cairo_set_source (cr, pat);
1234 cairo_pattern_destroy (pat);
1235 cairo_fill (cr);
1236
1237 /* Draw highlight */
1238 if (!toolbar->topmost)
1239 {
1240 cairo_move_to (cr, 0, 0.5);
1241 cairo_line_to (cr, width, 0.5);
1242 murrine_set_color_rgb (cr, top);
1243 cairo_stroke (cr);
1244 }
1245 break;
1246 }
1247 }
1248
1249 /* Draw shadow */
1250 murrine_set_color_rgb (cr, &dark);
1251 if (toolbar->style == 1 && widget->glazestyle == 2)
1252 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1253 else
1254 {
1255 cairo_move_to (cr, 0, height-0.5);
1256 cairo_line_to (cr, width, height-0.5);
1257 }
1258 cairo_stroke (cr);
1259 }
1260
1261 static void
murrine_get_frame_gap_clip(int x,int y,int width,int height,const FrameParameters * frame,MurrineRectangle * bevel,MurrineRectangle * border)1262 murrine_get_frame_gap_clip (int x, int y, int width, int height,
1263 const FrameParameters *frame,
1264 MurrineRectangle *bevel,
1265 MurrineRectangle *border)
1266 {
1267 switch (frame->gap_side)
1268 {
1269 case MRN_GAP_TOP:
1270 MURRINE_RECTANGLE_SET ((*bevel), 1.5+frame->gap_x, -0.5,
1271 frame->gap_width-3, 2.0);
1272 MURRINE_RECTANGLE_SET ((*border), 0.5+frame->gap_x, -0.5,
1273 frame->gap_width-2, 2.0);
1274 break;
1275 case MRN_GAP_BOTTOM:
1276 MURRINE_RECTANGLE_SET ((*bevel), 1.5+frame->gap_x, height-2.5,
1277 frame->gap_width-3, 2.0);
1278 MURRINE_RECTANGLE_SET ((*border), 0.5+frame->gap_x, height-1.5,
1279 frame->gap_width-2, 2.0);
1280 break;
1281 case MRN_GAP_LEFT:
1282 MURRINE_RECTANGLE_SET ((*bevel), -0.5, 1.5+frame->gap_x,
1283 2.0, frame->gap_width-3);
1284 MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5+frame->gap_x,
1285 1.0, frame->gap_width-2);
1286 break;
1287 case MRN_GAP_RIGHT:
1288 MURRINE_RECTANGLE_SET ((*bevel), width-2.5, 1.5+frame->gap_x,
1289 2.0, frame->gap_width-3);
1290 MURRINE_RECTANGLE_SET ((*border), width-1.5, 0.5+frame->gap_x,
1291 1.0, frame->gap_width-2);
1292 break;
1293 }
1294 }
1295
1296 static void
murrine_draw_frame(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FrameParameters * frame,int x,int y,int width,int height)1297 murrine_draw_frame (cairo_t *cr,
1298 const MurrineColors *colors,
1299 const WidgetParameters *widget,
1300 const FrameParameters *frame,
1301 int x, int y, int width, int height)
1302 {
1303 MurrineRGB *border = frame->border;
1304 MurrineRectangle bevel_clip;
1305 MurrineRectangle frame_clip;
1306 const MurrineRGB *dark = &colors->shade[3];
1307 MurrineRGB highlight, shadow_color;
1308
1309 murrine_shade (&colors->bg[0], 1.04, &highlight);
1310 murrine_shade (&colors->bg[0], 0.96, &shadow_color);
1311
1312 if (frame->shadow == MRN_SHADOW_NONE)
1313 return;
1314
1315 if (frame->gap_x != -1)
1316 murrine_get_frame_gap_clip (x, y, width, height,
1317 frame, &bevel_clip, &frame_clip);
1318
1319 cairo_translate (cr, x+0.5, y+0.5);
1320
1321 /* save everything */
1322 cairo_save (cr);
1323
1324 /* Set clip for the bevel */
1325 if (frame->gap_x != -1)
1326 {
1327 /* Set clip for gap */
1328 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1329 cairo_rectangle (cr, -0.5, -0.5, width, height);
1330 cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
1331 cairo_clip (cr);
1332 }
1333
1334 /* Draw the bevel */
1335 if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
1336 {
1337 murrine_set_color_rgb (cr, &highlight);
1338 if (frame->shadow == MRN_SHADOW_ETCHED_IN)
1339 murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
1340 else
1341 murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
1342 cairo_stroke (cr);
1343 }
1344 else if (frame->shadow != MRN_SHADOW_FLAT)
1345 {
1346 ShadowParameters shadow;
1347 shadow.corners = widget->corners;
1348 shadow.shadow = frame->shadow;
1349 murrine_draw_highlight_and_shade (cr, colors, &shadow, width, height, widget->roundness-1);
1350 }
1351
1352 /* restore the previous clip region */
1353 cairo_restore (cr);
1354 cairo_save (cr);
1355 if (frame->gap_x != -1)
1356 {
1357 /* Set clip for gap */
1358 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1359 cairo_rectangle (cr, -0.5, -0.5, width, height);
1360 cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
1361 cairo_clip (cr);
1362 }
1363
1364 /* Draw frame */
1365 if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
1366 {
1367 murrine_set_color_rgb (cr, dark);
1368 if (frame->shadow == MRN_SHADOW_ETCHED_IN)
1369 murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
1370 else
1371 murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
1372 }
1373 else
1374 {
1375 murrine_set_color_rgb (cr, border);
1376 murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1377 }
1378 cairo_stroke (cr);
1379 cairo_restore (cr);
1380 }
1381
1382 static void
murrine_draw_tab(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const TabParameters * tab,int x,int y,int width,int height)1383 murrine_draw_tab (cairo_t *cr,
1384 const MurrineColors *colors,
1385 const WidgetParameters *widget,
1386 const TabParameters *tab,
1387 int x, int y, int width, int height)
1388 {
1389 const MurrineRGB *stripe_fill = &colors->spot[1];
1390 const MurrineRGB *stripe_border = &colors->spot[2];
1391 const MurrineRGB *fill = &colors->bg[widget->state_type];
1392 const MurrineRGB *border = &colors->shade[!widget->active ? 5 : 4];
1393 cairo_pattern_t *pat;
1394
1395 /* Set clip */
1396 cairo_rectangle (cr, x, y, width, height);
1397 cairo_clip (cr);
1398 cairo_new_path (cr);
1399
1400 cairo_translate (cr, x+0.5, y+0.5);
1401
1402 /* Make the tabs slightly bigger than they should be, to create a gap */
1403 /* And calculate the strip size too, while you're at it */
1404 if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
1405 {
1406 height += 3.0;
1407
1408 if (tab->gap_side == MRN_GAP_TOP)
1409 cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
1410 }
1411 else
1412 {
1413 width += 3.0;
1414
1415 if (tab->gap_side == MRN_GAP_LEFT)
1416 cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
1417 }
1418
1419 /* Set tab shape */
1420 murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1421
1422 /* Draw fill */
1423 murrine_set_color_rgb (cr, fill);
1424 cairo_fill (cr);
1425
1426 if (widget->active)
1427 {
1428 MurrineRGB shade1, shade2, shade3, shade4, highlight;
1429 MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
1430 double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
1431 double lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
1432
1433 murrine_shade (fill, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1434 murrine_shade (fill, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1435 murrine_shade (fill, mrn_gradient_new.gradient_shades[2], &shade3);
1436 murrine_shade (fill, mrn_gradient_new.gradient_shades[3], &shade4);
1437
1438 switch (tab->gap_side)
1439 {
1440 case MRN_GAP_TOP:
1441 pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1442 break;
1443 case MRN_GAP_BOTTOM:
1444 pat = cairo_pattern_create_linear (0, 1, 0, height);
1445 break;
1446 case MRN_GAP_LEFT:
1447 pat = cairo_pattern_create_linear (width-2, 0, 1, 0);
1448 break;
1449 case MRN_GAP_RIGHT:
1450 pat = cairo_pattern_create_linear (1, 0, width-2, 0);
1451 break;
1452 }
1453
1454 murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1455
1456 murrine_pattern_add_color_stop_rgb (pat, 0.00, &shade1);
1457 murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade2);
1458 murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade3);
1459 murrine_pattern_add_color_stop_rgb (pat, 1.00, &shade4);
1460 cairo_set_source (cr, pat);
1461 cairo_fill (cr);
1462 cairo_pattern_destroy (pat);
1463
1464 /* Draw lightborder */
1465 murrine_shade (fill, lightborder_shade_new*highlight_shade_new, &highlight);
1466 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1467 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1468 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[2], &shade3);
1469 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[3], &shade4);
1470
1471 switch (tab->gap_side)
1472 {
1473 case MRN_GAP_TOP:
1474 pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1475 break;
1476 case MRN_GAP_BOTTOM:
1477 pat = cairo_pattern_create_linear (0, 1, 0, height);
1478 break;
1479 case MRN_GAP_LEFT:
1480 pat = cairo_pattern_create_linear (width-2, 0, 1, 0);
1481 break;
1482 case MRN_GAP_RIGHT:
1483 pat = cairo_pattern_create_linear (1, 0, width-2, 0);
1484 break;
1485 }
1486
1487 murrine_rounded_rectangle_closed (cr, 1, 1, width-3, height-3, widget->roundness, widget->corners);
1488
1489 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, 0.5);
1490 murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade2, 0.5);
1491 murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade3, 0.5);
1492 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade4, 0.5);
1493 cairo_set_source (cr, pat);
1494 cairo_stroke (cr);
1495 cairo_pattern_destroy (pat);
1496 }
1497 else
1498 {
1499 MurrineRGB shade1, shade2, shade3, shade4, highlight;
1500 MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
1501 double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
1502
1503 murrine_shade (fill, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1504 murrine_shade (fill, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1505 murrine_shade (fill, mrn_gradient_new.gradient_shades[2], &shade3);
1506 murrine_shade (fill, 1.0, &shade4);
1507
1508 /* Draw shade */
1509 switch (tab->gap_side)
1510 {
1511 case MRN_GAP_TOP:
1512 pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1513 break;
1514 case MRN_GAP_BOTTOM:
1515 pat = cairo_pattern_create_linear (0, 0, 0, height);
1516 break;
1517 case MRN_GAP_LEFT:
1518 pat = cairo_pattern_create_linear (width-2, 0, 0, 0);
1519 break;
1520 case MRN_GAP_RIGHT:
1521 pat = cairo_pattern_create_linear (0, 0, width, 0);
1522 break;
1523 }
1524
1525 murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1526
1527 murrine_pattern_add_color_stop_rgb (pat, 0.00, &shade1);
1528 murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade2);
1529 murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade3);
1530 murrine_pattern_add_color_stop_rgb (pat, 1.00, &shade4);
1531 cairo_set_source (cr, pat);
1532 cairo_fill (cr);
1533 cairo_pattern_destroy (pat);
1534
1535 /* Draw lightborder */
1536 murrine_shade (fill, widget->lightborder_shade*highlight_shade_new, &highlight);
1537 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1538 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1539 murrine_shade (&highlight, mrn_gradient_new.gradient_shades[2], &shade3);
1540 murrine_shade (fill, 1.04, &shade4); /* this value should change as draw_frame */
1541
1542 switch (tab->gap_side)
1543 {
1544 case MRN_GAP_TOP:
1545 pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1546 break;
1547 case MRN_GAP_BOTTOM:
1548 pat = cairo_pattern_create_linear (0, 0, 0, height);
1549 break;
1550 case MRN_GAP_LEFT:
1551 pat = cairo_pattern_create_linear (width-2, 0, 0, 0);
1552 break;
1553 case MRN_GAP_RIGHT:
1554 pat = cairo_pattern_create_linear (0, 0, width, 0);
1555 break;
1556 }
1557
1558 murrine_rounded_rectangle_closed (cr, 1, 1, width-3, height-3, widget->roundness, widget->corners);
1559
1560 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, 0.5);
1561 murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade2, 0.5);
1562 murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade3, 0.5);
1563 murrine_pattern_add_color_stop_rgb (pat, 1.00, &shade4);
1564 cairo_set_source (cr, pat);
1565 cairo_stroke (cr);
1566 cairo_pattern_destroy (pat);
1567 }
1568
1569 murrine_set_color_rgb (cr, border);
1570 murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1571 cairo_stroke (cr);
1572 }
1573
1574 static void
murrine_draw_separator(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1575 murrine_draw_separator (cairo_t *cr,
1576 const MurrineColors *colors,
1577 const WidgetParameters *widget,
1578 const SeparatorParameters *separator,
1579 int x, int y, int width, int height)
1580 {
1581 MurrineRGB dark, highlight;
1582 murrine_shade (&colors->bg[0], murrine_get_contrast(0.7, widget->contrast), &dark);
1583 murrine_shade (&colors->bg[0], murrine_get_contrast(1.3, widget->contrast), &highlight);
1584
1585 if (separator->horizontal)
1586 {
1587 cairo_translate (cr, x, y+0.5);
1588
1589 switch (separator->style)
1590 {
1591 default:
1592 case 0:
1593 murrine_set_color_rgba (cr, &dark, 0.5);
1594 break;
1595 case 1:
1596 {
1597 cairo_pattern_t *pat;
1598 pat = cairo_pattern_create_linear (0, 0, width, 0);
1599 murrine_pattern_add_color_stop_rgba (pat, 0.00, &dark, 0.0);
1600 murrine_pattern_add_color_stop_rgba (pat, 0.25, &dark, 0.5);
1601 murrine_pattern_add_color_stop_rgba (pat, 0.75, &dark, 0.5);
1602 murrine_pattern_add_color_stop_rgba (pat, 1.00, &dark, 0.0);
1603 cairo_set_source (cr, pat);
1604 cairo_pattern_destroy (pat);
1605 break;
1606 }
1607 }
1608
1609 cairo_move_to (cr, 0.0, 0.0);
1610 cairo_line_to (cr, width+1, 0.0);
1611 cairo_stroke (cr);
1612
1613 switch (separator->style)
1614 {
1615 default:
1616 case 0:
1617 murrine_set_color_rgba (cr, &highlight, 0.5);
1618 break;
1619 case 1:
1620 {
1621 cairo_pattern_t *pat;
1622 pat = cairo_pattern_create_linear (0, 0, width, 0);
1623 murrine_pattern_add_color_stop_rgba (pat, 0.00, &highlight, 0.0);
1624 murrine_pattern_add_color_stop_rgba (pat, 0.25, &highlight, 0.5);
1625 murrine_pattern_add_color_stop_rgba (pat, 0.75, &highlight, 0.5);
1626 murrine_pattern_add_color_stop_rgba (pat, 1.00, &highlight, 0.0);
1627 cairo_set_source (cr, pat);
1628 cairo_pattern_destroy (pat);
1629 break;
1630 }
1631 case 3:
1632 return;
1633 break;
1634 }
1635
1636 cairo_move_to (cr, 0.0, 1.0);
1637 cairo_line_to (cr, width, 1.0);
1638 cairo_stroke (cr);
1639 }
1640 else
1641 {
1642 cairo_translate (cr, x+0.5, y);
1643
1644 switch (separator->style)
1645 {
1646 default:
1647 case 0:
1648 murrine_set_color_rgba (cr, &dark, 0.5);
1649 break;
1650 case 1:
1651 {
1652 cairo_pattern_t *pat;
1653 pat = cairo_pattern_create_linear (0, 0, 0, height);
1654 murrine_pattern_add_color_stop_rgba (pat, 0.00, &dark, 0.0);
1655 murrine_pattern_add_color_stop_rgba (pat, 0.25, &dark, 0.5);
1656 murrine_pattern_add_color_stop_rgba (pat, 0.75, &dark, 0.5);
1657 murrine_pattern_add_color_stop_rgba (pat, 1.00, &dark, 0.0);
1658 cairo_set_source (cr, pat);
1659 cairo_pattern_destroy (pat);
1660 break;
1661 }
1662 }
1663 cairo_move_to (cr, 0.0, 0.0);
1664 cairo_line_to (cr, 0.0, height);
1665 cairo_stroke (cr);
1666
1667 switch (separator->style)
1668 {
1669 default:
1670 case 0:
1671 murrine_set_color_rgba (cr, &highlight, 0.5);
1672 break;
1673 case 1:
1674 {
1675 cairo_pattern_t *pat;
1676 pat = cairo_pattern_create_linear (0, 0, 0, height);
1677 murrine_pattern_add_color_stop_rgba (pat, 0.00, &highlight, 0.0);
1678 murrine_pattern_add_color_stop_rgba (pat, 0.25, &highlight, 0.5);
1679 murrine_pattern_add_color_stop_rgba (pat, 0.75, &highlight, 0.5);
1680 murrine_pattern_add_color_stop_rgba (pat, 1.00, &highlight, 0.0);
1681 cairo_set_source (cr, pat);
1682 cairo_pattern_destroy (pat);
1683 break;
1684 }
1685 case 3:
1686 return;
1687 break;
1688 }
1689
1690 cairo_move_to (cr, 1.0, 0.0);
1691 cairo_line_to (cr, 1.0, height);
1692 cairo_stroke (cr);
1693 }
1694 }
1695
1696 static void
murrine_draw_combo_separator(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1697 murrine_draw_combo_separator (cairo_t *cr,
1698 const MurrineColors *colors,
1699 const WidgetParameters *widget,
1700 int x, int y, int width, int height)
1701 {
1702 const MurrineRGB *dark = &colors->shade[6];
1703
1704 cairo_translate (cr, x+0.5, y);
1705
1706 murrine_set_color_rgba (cr, dark, 0.4);
1707 cairo_move_to (cr, 0.0, 0.0);
1708 cairo_line_to (cr, 0.0, height+1);
1709 cairo_stroke (cr);
1710 }
1711
1712 static void
murrine_draw_list_view_header(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ListViewHeaderParameters * header,int x,int y,int width,int height)1713 murrine_draw_list_view_header (cairo_t *cr,
1714 const MurrineColors *colors,
1715 const WidgetParameters *widget,
1716 const ListViewHeaderParameters *header,
1717 int x, int y, int width, int height)
1718 {
1719 const MurrineRGB *fill = &colors->bg[widget->state_type];
1720 MurrineRGB border = colors->shade[3];
1721 MurrineRGB grip = colors->shade[3];
1722 MurrineRGB highlight;
1723
1724 murrine_shade (&border, 1.3, &highlight);
1725
1726 cairo_translate (cr, x, y);
1727
1728 if (header->order & MRN_ORDER_FIRST)
1729 {
1730 cairo_move_to (cr, 0.5, height-1);
1731 cairo_line_to (cr, 0.5, 0.5);
1732 }
1733 else
1734 cairo_move_to (cr, 0.0, 0.5);
1735
1736 /* Effects */
1737 switch (header->style)
1738 {
1739 case 0:
1740 murrine_set_color_rgb (cr, &highlight);
1741 cairo_line_to (cr, width, 0.5);
1742 cairo_stroke (cr);
1743 break;
1744 case 1:
1745 cairo_rectangle (cr, 0, 0, width, height);
1746
1747 murrine_draw_glaze (cr, fill,
1748 widget->glow_shade, widget->highlight_shade, widget->glazestyle != 0 ? widget->lightborder_shade : 1.0,
1749 widget->mrn_gradient, widget, 0, 0, width, height-1,
1750 widget->roundness, widget->corners, TRUE);
1751
1752 if (widget->mrn_gradient.has_border_colors)
1753 {
1754 border = grip = widget->mrn_gradient.border_colors[1];
1755 grip = widget->mrn_gradient.border_colors[0];
1756 }
1757 break;
1758 case 2:
1759 border = colors->shade[4];
1760 MurrineRGB shadow_header;
1761 murrine_shade (fill, 0.925, &shadow_header);
1762
1763 if (!widget->mrn_gradient.gradients)
1764 {
1765 murrine_set_color_rgb (cr, &shadow_header);
1766 cairo_rectangle (cr, 0.0, height-3.0, width, 2.0);
1767 }
1768 else
1769 {
1770 cairo_pattern_t *pat;
1771 pat = cairo_pattern_create_linear (0.0, height-4.0, 0.0, height-1.0);
1772 murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow_header, 0.0);
1773 murrine_pattern_add_color_stop_rgb (pat, 1.0, &shadow_header);
1774 cairo_set_source (cr, pat);
1775 cairo_pattern_destroy (pat);
1776 cairo_rectangle (cr, 0.0, height-4.0, width, 3.0);
1777 }
1778 cairo_fill (cr);
1779 break;
1780 }
1781 murrine_shade (&border, widget->mrn_gradient.border_shades[1], &border);
1782
1783 /* Draw bottom border */
1784 murrine_set_color_rgb (cr, &border);
1785 cairo_move_to (cr, 0.0, height-0.5);
1786 cairo_line_to (cr, width, height-0.5);
1787 cairo_stroke (cr);
1788
1789 /* Draw resize grip */
1790 if ((widget->ltr && !(header->order & MRN_ORDER_LAST)) ||
1791 (!widget->ltr && !(header->order & MRN_ORDER_FIRST)) || header->resizable)
1792 {
1793 murrine_shade (&grip, widget->mrn_gradient.border_shades[0], &grip);
1794
1795 if (header->style == 1 && widget->glazestyle > 0)
1796 {
1797 cairo_translate (cr, width-0.5, 0);
1798
1799 murrine_set_color_rgb (cr, &grip);
1800 cairo_move_to (cr, 0, 0);
1801 cairo_line_to (cr, 0, height-1);
1802 cairo_stroke (cr);
1803 }
1804 else
1805 {
1806 SeparatorParameters separator;
1807 separator.horizontal = FALSE;
1808
1809 murrine_draw_separator (cr, colors, widget, &separator, width-1.5, 4.0, 2, height-8.0);
1810 }
1811 }
1812 }
1813
1814 static void
murrine_draw_menuitem(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menuitemstyle)1815 murrine_draw_menuitem (cairo_t *cr,
1816 const MurrineColors *colors,
1817 const WidgetParameters *widget,
1818 int x, int y, int width, int height,
1819 int menuitemstyle)
1820 {
1821 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
1822 MurrineRGB border = colors->spot[2];
1823 MurrineRGB fill = colors->spot[1];
1824
1825 murrine_get_fill_color (&fill, &mrn_gradient_new);
1826
1827 cairo_translate (cr, x, y);
1828 murrine_rounded_rectangle_closed (cr, 0, 0, width, height, widget->roundness, widget->corners);
1829
1830 switch (menuitemstyle)
1831 {
1832 case 0:
1833 mrn_gradient_new.has_border_colors = FALSE;
1834 mrn_gradient_new.has_gradient_colors = FALSE;
1835
1836 murrine_set_gradient (cr, &fill, mrn_gradient_new, 0, 0, 0, height, mrn_gradient_new.gradients, FALSE);
1837 cairo_fill (cr);
1838
1839 murrine_set_color_rgba (cr, &border, 0.15);
1840 murrine_rounded_rectangle_closed (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
1841 cairo_fill_preserve (cr);
1842 break;
1843 default:
1844 case 1:
1845 cairo_clip_preserve (cr);
1846
1847 murrine_draw_glaze (cr, &fill,
1848 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1849 mrn_gradient_new, widget, 1, 1, width-2, height-2,
1850 widget->roundness, widget->corners, TRUE);
1851 break;
1852 case 2:
1853 {
1854 murrine_set_gradient (cr, &fill, mrn_gradient_new, 0, 0, 0, height, mrn_gradient_new.gradients, FALSE);
1855 cairo_fill (cr);
1856
1857 MurrineRGB effect;
1858 double tile_pos = 0;
1859 double stroke_width;
1860 int x_step;
1861 stroke_width = height*2;
1862 x_step = (((float)stroke_width/10));
1863
1864 murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &effect);
1865
1866 cairo_save (cr);
1867 /* Draw strokes */
1868 while (stroke_width > 0 && tile_pos <= width+x_step)
1869 {
1870 cairo_move_to (cr, stroke_width/2-x_step, 0);
1871 cairo_line_to (cr, stroke_width-x_step, 0);
1872 cairo_line_to (cr, stroke_width/2-x_step, height);
1873 cairo_line_to (cr, -x_step, height);
1874
1875 cairo_translate (cr, stroke_width, 0);
1876 tile_pos += stroke_width;
1877 }
1878 murrine_set_color_rgba (cr, &effect, 0.15);
1879 cairo_fill (cr);
1880 cairo_restore (cr);
1881 break;
1882 }
1883 }
1884
1885 murrine_draw_border (cr, &border,
1886 0.5, 0.5, width-1, height-1,
1887 widget->roundness, widget->corners,
1888 mrn_gradient_new, 0.8);
1889 }
1890
1891 static void
murrine_draw_scrollbar_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1892 murrine_draw_scrollbar_trough (cairo_t *cr,
1893 const MurrineColors *colors,
1894 const WidgetParameters *widget,
1895 const ScrollBarParameters *scrollbar,
1896 int x, int y, int width, int height)
1897 {
1898 MurrineRGB border;
1899 MurrineRGB fill;
1900
1901 murrine_shade (&widget->parentbg,
1902 murrine_get_contrast (scrollbar->stepperstyle != 1 ? 0.86 : 0.8, widget->contrast),
1903 &border);
1904 murrine_shade (&widget->parentbg, scrollbar->stepperstyle != 1 ? 0.97 : 1.026, &fill);
1905 /*
1906 murrine_shade (&colors->bg[widget->state_type],
1907 murrine_get_contrast (scrollbar->stepperstyle < 1 ? 0.86 : 0.8, widget->contrast),
1908 &border_bg);
1909 murrine_shade (&colors->bg[widget->state_type], scrollbar->stepperstyle < 1 ? 0.97 : 1.026, &fill_bg);
1910 murrine_mix_color (&border_bg, &border, 0.5, &border);
1911 murrine_mix_color (&fill_bg, &fill, 0.5, &fill);
1912 */
1913 if (!scrollbar->horizontal)
1914 {
1915 cairo_translate (cr, x, y);
1916 }
1917 else
1918 {
1919 int tmp = height;
1920 rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
1921 height = width;
1922 width = tmp;
1923 }
1924
1925 /* Draw fill */
1926 murrine_draw_trough (cr, &fill, 0, 0, width, height, widget->roundness, widget->corners, widget->mrn_gradient, 1.0, FALSE);
1927
1928 if (scrollbar->stepperstyle == 3)
1929 {
1930 uint8 corners;
1931 MurrineRGB fill_stepper;
1932 MurrineRGB border_stepper;
1933
1934 murrine_shade (&widget->parentbg, 1.02, &fill_stepper);
1935 murrine_shade (&border, (widget->mrn_gradient.trough_shades[0]+widget->mrn_gradient.trough_shades[1])/2.0, &border_stepper);
1936
1937 cairo_save (cr);
1938
1939 murrine_rounded_rectangle_closed (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
1940 cairo_clip (cr);
1941
1942 corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
1943 murrine_rounded_rectangle_inverted (cr, 0.5, 0.5, width-1, scrollbar->steppersize, widget->roundness, corners);
1944 murrine_set_color_rgb (cr, &fill_stepper);
1945 cairo_fill_preserve (cr);
1946 murrine_draw_trough_border_from_path (cr, &border,0.5, 0.5, width-1, scrollbar->steppersize, widget->mrn_gradient, 1.0, FALSE);
1947
1948 corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
1949 murrine_rounded_rectangle_inverted (cr, 0.5, height-scrollbar->steppersize-0.5, width-1, scrollbar->steppersize, widget->roundness, corners);
1950 murrine_set_color_rgb (cr, &fill_stepper);
1951 cairo_fill_preserve (cr);
1952 murrine_draw_trough_border_from_path (cr, &border, 0.5, height-scrollbar->steppersize-0.5, width-1, scrollbar->steppersize, widget->mrn_gradient, 1.0, FALSE);
1953
1954 cairo_restore (cr);
1955 }
1956
1957 /* Draw border */
1958 if (!scrollbar->within_bevel)
1959 murrine_draw_trough_border (cr, &border, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners, widget->mrn_gradient, 1.0, FALSE);
1960 else
1961 {
1962 murrine_shade (&border, widget->mrn_gradient.trough_shades[0], &border);
1963 murrine_set_color_rgb (cr, &border);
1964 cairo_move_to (cr, 0.5, 0);
1965 cairo_line_to (cr, 0.5, height);
1966 cairo_stroke (cr);
1967 }
1968 }
1969
1970 static void
murrine_draw_scrollbar_stepper(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1971 murrine_draw_scrollbar_stepper (cairo_t *cr,
1972 const MurrineColors *colors,
1973 const WidgetParameters *widget,
1974 const ScrollBarParameters *scrollbar,
1975 int x, int y, int width, int height)
1976 {
1977 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
1978 double border_stop_mid = ((mrn_gradient_new.border_shades[0])+
1979 (mrn_gradient_new.border_shades[1]))/2.0;
1980 MurrineRGB border;
1981 MurrineRGB fill = colors->bg[widget->state_type];
1982
1983 murrine_get_fill_color (&fill, &mrn_gradient_new);
1984 murrine_shade (&colors->shade[6], 0.95, &border);
1985
1986 mrn_gradient_new.border_shades[0] = border_stop_mid;
1987 mrn_gradient_new.border_shades[1] = border_stop_mid;
1988
1989 if (!scrollbar->horizontal)
1990 murrine_exchange_axis (cr, &x, &y, &width, &height);
1991
1992 /* Border color */
1993 murrine_mix_color (&border, &fill, 0.4, &border);
1994
1995 cairo_translate (cr, x, y);
1996
1997 cairo_save (cr);
1998
1999 murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, widget->corners);
2000 cairo_clip_preserve(cr);
2001
2002 murrine_draw_glaze (cr, &fill,
2003 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2004 mrn_gradient_new, widget, 1, 1, width-2, height-2,
2005 widget->roundness, widget->corners, TRUE);
2006
2007 cairo_restore (cr);
2008
2009 murrine_draw_border (cr, &border,
2010 0.5, 0.5, width-1, height-1,
2011 widget->roundness, widget->corners,
2012 mrn_gradient_new, 1.0);
2013 }
2014
2015 static void
murrine_draw_scrollbar_slider(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)2016 murrine_draw_scrollbar_slider (cairo_t *cr,
2017 const MurrineColors *colors,
2018 const WidgetParameters *widget,
2019 const ScrollBarParameters *scrollbar,
2020 int x, int y, int width, int height)
2021 {
2022 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2023 double border_stop_mid = ((mrn_gradient_new.border_shades[0])+
2024 (mrn_gradient_new.border_shades[1]))/2.0;
2025 MurrineRGB fill = scrollbar->has_color ? scrollbar->color : colors->bg[widget->state_type];
2026 MurrineRGB border;
2027 uint8 corners = widget->corners;
2028
2029 murrine_get_fill_color (&fill, &mrn_gradient_new);
2030
2031 if (scrollbar->stepperstyle != 1 && scrollbar->stepperstyle != 3)
2032 {
2033 if (scrollbar->junction & MRN_JUNCTION_BEGIN)
2034 {
2035 if (scrollbar->horizontal)
2036 {
2037 x -= 1;
2038 width += 1;
2039 }
2040 else
2041 {
2042 y -= 1;
2043 height += 1;
2044 }
2045 }
2046 if (scrollbar->junction & MRN_JUNCTION_END)
2047 {
2048 if (scrollbar->horizontal)
2049 width += 1;
2050 else
2051 height += 1;
2052 }
2053 }
2054
2055 if (scrollbar->stepperstyle == 2)
2056 {
2057 if (scrollbar->junction & MRN_JUNCTION_BEGIN)
2058 {
2059 if (scrollbar->horizontal)
2060 corners ^= MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
2061 else
2062 corners ^= MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
2063 }
2064 if (scrollbar->junction & MRN_JUNCTION_END)
2065 {
2066 if (scrollbar->horizontal)
2067 corners ^= MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
2068 else
2069 corners ^= MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
2070 }
2071 }
2072
2073 murrine_shade (&colors->shade[6], 0.95, &border);
2074
2075 mrn_gradient_new.border_shades[0] = border_stop_mid;
2076 mrn_gradient_new.border_shades[1] = border_stop_mid;
2077
2078 if (widget->prelight && scrollbar->has_color)
2079 murrine_shade (&fill, scrollbar->prelight_shade, &fill);
2080
2081 murrine_mix_color (&border, &fill, 0.4, &border);
2082
2083 if (scrollbar->horizontal)
2084 cairo_translate (cr, x, y);
2085 else
2086 {
2087 int tmp = height;
2088 rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
2089 height = width;
2090 width = tmp;
2091 }
2092
2093 cairo_save (cr);
2094
2095 murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, corners);
2096 cairo_clip_preserve (cr);
2097
2098 murrine_draw_glaze (cr, &fill,
2099 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2100 mrn_gradient_new, widget, 1, 1, width-2, height-2,
2101 widget->roundness, corners, TRUE);
2102
2103 /* Draw the options */
2104 MurrineRGB style;
2105 if (scrollbar->style > 0)
2106 murrine_shade (&fill, 0.55, &style);
2107
2108 switch (scrollbar->style)
2109 {
2110 case 1:
2111 {
2112 int circ_radius = 2;
2113 int circ_space = 5;
2114 int i;
2115 int x1 = circ_space+circ_radius;
2116 int y1 = height/2;
2117 for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
2118 {
2119 cairo_move_to (cr, i, 1);
2120 cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
2121
2122 x1 += 2*circ_radius+circ_space;
2123
2124 cairo_close_path (cr);
2125 murrine_set_color_rgba (cr, &style, 0.15);
2126 cairo_fill (cr);
2127 }
2128 break;
2129 }
2130 case 3:
2131 case 4:
2132 {
2133 int counter = -width;
2134 cairo_save (cr);
2135 cairo_rectangle (cr, 1, 1, width-2, height-2);
2136 cairo_clip (cr);
2137 cairo_new_path (cr);
2138 cairo_set_line_width (cr, 5.0); /* stroke width */
2139 murrine_set_color_rgba (cr, &style, 0.08);
2140 while (counter < height)
2141 {
2142 cairo_move_to (cr, width, counter);
2143 cairo_line_to (cr, 0, counter+width);
2144 cairo_stroke (cr);
2145 counter += 12;
2146 }
2147 cairo_restore (cr);
2148 break;
2149 }
2150 case 5:
2151 case 6:
2152 {
2153 int stroke_width = 7;
2154 int stroke_space = 5;
2155 int i;
2156 murrine_set_color_rgba (cr, &style, 0.08);
2157 for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
2158 {
2159 cairo_move_to (cr, i, 1);
2160 cairo_rel_line_to (cr, 0, height-2);
2161 cairo_rel_line_to (cr, stroke_width, 0);
2162 cairo_rel_line_to (cr, 0, -(height-2));
2163 cairo_fill (cr);
2164 }
2165 break;
2166 }
2167 }
2168 /* Draw the handle */
2169 if (scrollbar->style > 0 && scrollbar->style % 2 == 0)
2170 {
2171 double bar_x = width/2-3.5;
2172 int i;
2173
2174 switch (scrollbar->handlestyle)
2175 {
2176 default:
2177 case 0:
2178 {
2179 for (i=0; i<3; i++)
2180 {
2181 cairo_move_to (cr, bar_x, 5);
2182 cairo_line_to (cr, bar_x, height-5);
2183 murrine_set_color_rgb (cr, &border);
2184 cairo_stroke (cr);
2185
2186 bar_x += 3;
2187 }
2188 break;
2189 }
2190 case 1:
2191 {
2192 MurrineRGB inset;
2193 murrine_shade (&fill, 1.08, &inset);
2194
2195 for (i=0; i<3; i++)
2196 {
2197 cairo_move_to (cr, bar_x, 5);
2198 cairo_line_to (cr, bar_x, height-5);
2199 murrine_set_color_rgb (cr, &border);
2200 cairo_stroke (cr);
2201
2202 cairo_move_to (cr, bar_x+1, 5);
2203 cairo_line_to (cr, bar_x+1, height-5);
2204 murrine_set_color_rgb (cr, &inset);
2205 cairo_stroke (cr);
2206
2207 bar_x += 3;
2208 }
2209 break;
2210 }
2211 case 2:
2212 {
2213 MurrineRGB inset;
2214 murrine_shade (&fill, 1.08, &inset);
2215
2216 bar_x++;
2217
2218 for (i=0; i<3; i++)
2219 {
2220 cairo_move_to (cr, bar_x, 5);
2221 cairo_line_to (cr, bar_x, height-5);
2222 murrine_set_color_rgb (cr, &border);
2223 cairo_stroke (cr);
2224
2225 cairo_move_to (cr, bar_x+1, 4);
2226 cairo_line_to (cr, bar_x+1, height-5);
2227 murrine_set_color_rgb (cr, &inset);
2228 cairo_stroke (cr);
2229
2230 bar_x += 2;
2231 }
2232 break;
2233 }
2234 }
2235 }
2236
2237 cairo_restore (cr);
2238
2239 murrine_draw_border (cr, &border,
2240 0.5, 0.5, width-1, height-1,
2241 widget->roundness, corners,
2242 mrn_gradient_new, 1.0);
2243 }
2244
2245 static void
murrine_draw_selected_cell(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CellParameters * cell,int x,int y,int width,int height)2246 murrine_draw_selected_cell (cairo_t *cr,
2247 const MurrineColors *colors,
2248 const WidgetParameters *widget,
2249 const CellParameters *cell,
2250 int x, int y, int width, int height)
2251 {
2252 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
2253 cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
2254 MurrineRGB fill = widget->focus ? colors->base[widget->state_type] :
2255 colors->base[GTK_STATE_ACTIVE];
2256 MurrineRGB border;
2257 murrine_shade (&fill, (cell->style != 0 ? !widget->mrn_gradient.gradients ? 0.9 : 0.95 : 1.0), &border);
2258
2259 cairo_save (cr);
2260 cairo_translate (cr, x, y);
2261
2262 murrine_set_gradient (cr, &fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
2263 cairo_rectangle (cr, 0, 0, width, height);
2264 cairo_fill (cr);
2265
2266 murrine_set_color_rgb (cr, &border);
2267 cairo_move_to (cr, 0, 0.5);
2268 cairo_rel_line_to (cr, width, 0);
2269 cairo_move_to (cr, 0, height-0.5);
2270 cairo_rel_line_to (cr, width, 0);
2271 cairo_stroke (cr);
2272
2273 cairo_restore (cr);
2274 }
2275
2276 static void
murrine_draw_statusbar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2277 murrine_draw_statusbar (cairo_t *cr,
2278 const MurrineColors *colors,
2279 const WidgetParameters *widget,
2280 int x, int y, int width, int height)
2281 {
2282 const MurrineRGB *dark = &colors->shade[3];
2283 const MurrineRGB *highlight = &colors->shade[0];
2284
2285 cairo_translate (cr, x, y+0.5);
2286
2287 murrine_set_color_rgb (cr, dark);
2288 cairo_move_to (cr, 0, 0);
2289 cairo_line_to (cr, width, 0);
2290 cairo_stroke (cr);
2291
2292 murrine_set_color_rgb (cr, highlight);
2293 cairo_move_to (cr, 0, 1);
2294 cairo_line_to (cr, width, 1);
2295 cairo_stroke (cr);
2296 }
2297
2298 static void
murrine_draw_menu_frame(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menustyle)2299 murrine_draw_menu_frame (cairo_t *cr,
2300 const MurrineColors *colors,
2301 const WidgetParameters *widget,
2302 int x, int y, int width, int height,
2303 int menustyle)
2304 {
2305 cairo_translate (cr, x, y);
2306
2307 switch (menustyle)
2308 {
2309 case 1:
2310 {
2311 MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
2312 MurrineRGB border2;
2313 murrine_shade (fill, 0.5, &border2);
2314
2315 murrine_set_color_rgb (cr, &border2);
2316 cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
2317 cairo_stroke_preserve (cr);
2318
2319 murrine_set_color_rgb (cr, fill);
2320 cairo_fill (cr);
2321 }
2322 default:
2323 case 0:
2324 {
2325 const MurrineRGB *border = &colors->shade[5];
2326
2327 murrine_set_color_rgb (cr, border);
2328 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
2329 cairo_stroke (cr);
2330 break;
2331 }
2332 case 2:
2333 {
2334 const MurrineRGB *border = &colors->shade[2];
2335 MurrineRGB fill;
2336 raico_blur_t* blur = NULL;
2337 cairo_t *cr_surface;
2338 cairo_surface_t *surface;
2339 cairo_pattern_t *pat;
2340 int bradius = 30;
2341 int bheight = MIN (height, 300);
2342
2343 murrine_shade (&colors->bg[0], 1.14, &fill);
2344
2345 murrine_set_color_rgb (cr, border);
2346 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
2347 cairo_stroke (cr);
2348
2349 /* draw glow */
2350 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, bheight);
2351 cr_surface = cairo_create (surface);
2352 blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
2353 raico_blur_set_radius (blur, bradius);
2354 cairo_set_line_width (cr_surface, 1.0);
2355 cairo_rectangle (cr_surface, bradius, bradius-15, width-bradius*2, bheight-bradius*2+15);
2356 murrine_set_color_rgb (cr_surface, &fill);
2357 cairo_fill (cr_surface);
2358 raico_blur_apply (blur, surface);
2359 cairo_rectangle (cr_surface, 0, -15, width, bheight+15);
2360 pat = cairo_pattern_create_linear (0, -15, 0.0, bheight+15);
2361 murrine_pattern_add_color_stop_rgba (pat, 0.25, &colors->bg[0], 0.0);
2362 murrine_pattern_add_color_stop_rgba (pat, 1.0, &colors->bg[0], 1.0);
2363 cairo_set_source (cr_surface, pat);
2364 cairo_pattern_destroy (pat);
2365 cairo_fill (cr_surface);
2366 cairo_set_source_surface (cr, surface, 0, 0);
2367 cairo_paint (cr);
2368 cairo_surface_destroy (surface);
2369 cairo_destroy (cr_surface);
2370 break;
2371 }
2372 case 3:
2373 {
2374 MurrineRGB border;
2375 MurrineRGB fill;
2376 raico_blur_t* blur = NULL;
2377 cairo_t *cr_surface;
2378 cairo_surface_t *surface;
2379 cairo_pattern_t *pat;
2380 int bradius = 30;
2381 int bheight = MIN (height, 300);
2382
2383 murrine_shade (&colors->bg[0], murrine_get_contrast(1.1, widget->contrast), &border);
2384 murrine_shade (&colors->bg[0], 0.96, &fill);
2385
2386 murrine_set_color_rgb (cr, &border);
2387 cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
2388 cairo_stroke (cr);
2389
2390 /* draw glow */
2391 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, bheight);
2392 cr_surface = cairo_create (surface);
2393 blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
2394 raico_blur_set_radius (blur, bradius);
2395 cairo_set_line_width (cr_surface, 1.0);
2396 cairo_rectangle (cr_surface, bradius, bradius-15, width-bradius*2, bheight-bradius*2+15);
2397 murrine_set_color_rgb (cr_surface, &fill);
2398 cairo_fill (cr_surface);
2399 raico_blur_apply (blur, surface);
2400 cairo_rectangle (cr_surface, 0, -15, width, bheight+15);
2401 pat = cairo_pattern_create_linear (0, -15, 0.0, bheight+15);
2402 murrine_pattern_add_color_stop_rgba (pat, 0.25, &colors->bg[0], 0.0);
2403 murrine_pattern_add_color_stop_rgba (pat, 1.0, &colors->bg[0], 1.0);
2404 cairo_set_source (cr_surface, pat);
2405 cairo_pattern_destroy (pat);
2406 cairo_fill (cr_surface);
2407 cairo_set_source_surface (cr, surface, 0, 0);
2408 cairo_paint (cr);
2409 cairo_surface_destroy (surface);
2410 cairo_destroy (cr_surface);
2411 break;
2412 }
2413 }
2414 }
2415
2416 static void
murrine_draw_tooltip(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2417 murrine_draw_tooltip (cairo_t *cr,
2418 const MurrineColors *colors,
2419 const WidgetParameters *widget,
2420 int x, int y, int width, int height)
2421 {
2422 MurrineRGB border;
2423 MurrineRGB fill = colors->bg[widget->state_type];
2424 MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 2.0);
2425 double glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
2426 double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2427
2428 murrine_shade (&fill, murrine_get_contrast(0.6, widget->contrast), &border);
2429 murrine_get_fill_color (&fill, &mrn_gradient_new);
2430
2431 cairo_save (cr);
2432
2433 cairo_translate (cr, x, y);
2434
2435 cairo_rectangle (cr, 1, 1, width-2, height-2);
2436
2437 murrine_draw_glaze (cr, &colors->bg[widget->state_type],
2438 glow_shade_new, highlight_shade_new, widget->lightborder_shade,
2439 mrn_gradient_new, widget, 1, 1, width-2, height-2,
2440 widget->roundness, widget->corners, TRUE);
2441
2442 murrine_draw_border (cr, &border,
2443 0.5, 0.5, width-1, height-1,
2444 widget->roundness, widget->corners,
2445 mrn_gradient_new, 1.0);
2446
2447 cairo_restore (cr);
2448 }
2449
2450 static void
murrine_draw_iconview(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2451 murrine_draw_iconview (cairo_t *cr,
2452 const MurrineColors *colors,
2453 const WidgetParameters *widget,
2454 int x, int y, int width, int height)
2455 {
2456 MurrineRGB border;
2457 MurrineRGB fill = widget->focus ? colors->base[widget->state_type] :
2458 colors->base[GTK_STATE_ACTIVE];
2459
2460 murrine_shade (&fill, murrine_get_contrast(0.6, widget->contrast), &border);
2461 murrine_get_fill_color (&fill, &widget->mrn_gradient);
2462
2463 cairo_save (cr);
2464
2465 cairo_translate (cr, x, y);
2466 cairo_save (cr);
2467
2468 murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, widget->corners);
2469 cairo_clip_preserve (cr);
2470
2471 murrine_draw_glaze (cr, &fill,
2472 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2473 widget->mrn_gradient, widget, 1, 1, width-2, height-2,
2474 widget->roundness-1, widget->corners, TRUE);
2475
2476 cairo_restore (cr);
2477
2478 murrine_draw_border (cr, &border,
2479 0.5, 0.5, width-1, height-1,
2480 widget->roundness, widget->corners,
2481 widget->mrn_gradient, 1.0);
2482
2483 cairo_restore (cr);
2484 }
2485
2486 static void
murrine_draw_handle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const HandleParameters * handle,int x,int y,int width,int height)2487 murrine_draw_handle (cairo_t *cr,
2488 const MurrineColors *colors,
2489 const WidgetParameters *widget,
2490 const HandleParameters *handle,
2491 int x, int y, int width, int height)
2492 {
2493 int bar_height;
2494 int bar_width = 4;
2495 int i, bar_y = 1;
2496 int num_bars, bar_spacing;
2497 num_bars = 3;
2498 bar_spacing = 3;
2499 bar_height = num_bars*bar_spacing;
2500
2501 if (handle->horizontal)
2502 {
2503 int tmp = height;
2504 rotate_mirror_translate (cr, M_PI/2, x+0.5+width/2-bar_height/2, y+height/2-bar_width/2, FALSE, FALSE);
2505 height = width;
2506 width = tmp;
2507 }
2508 else
2509 {
2510 cairo_translate (cr, x+width/2-bar_width/2, y+height/2-bar_height/2+0.5);
2511 }
2512
2513 switch (handle->style)
2514 {
2515 default:
2516 case 0:
2517 {
2518 for (i=0; i<num_bars; i++)
2519 {
2520 cairo_move_to (cr, 0, bar_y);
2521 cairo_line_to (cr, bar_width, bar_y);
2522 murrine_set_color_rgb (cr, &colors->shade[4]);
2523 cairo_stroke (cr);
2524
2525 bar_y += bar_spacing;
2526 }
2527 break;
2528 }
2529 case 1:
2530 {
2531 for (i=0; i<num_bars; i++)
2532 {
2533 cairo_move_to (cr, 0, bar_y);
2534 cairo_line_to (cr, bar_width, bar_y);
2535 murrine_set_color_rgb (cr, &colors->shade[4]);
2536 cairo_stroke (cr);
2537
2538 cairo_move_to (cr, 0, bar_y+1);
2539 cairo_line_to (cr, bar_width, bar_y+1);
2540 murrine_set_color_rgb (cr, &colors->shade[0]);
2541 cairo_stroke (cr);
2542
2543 bar_y += bar_spacing;
2544 }
2545 break;
2546 }
2547 case 2:
2548 {
2549 bar_y++;
2550
2551 for (i=0; i<num_bars; i++)
2552 {
2553 cairo_move_to (cr, 0, bar_y);
2554 cairo_line_to (cr, bar_width, bar_y);
2555 murrine_set_color_rgb (cr, &colors->shade[4]);
2556 cairo_stroke (cr);
2557
2558 cairo_move_to (cr, 0, bar_y+1);
2559 cairo_line_to (cr, bar_width, bar_y+1);
2560 murrine_set_color_rgb (cr, &colors->shade[0]);
2561 cairo_stroke (cr);
2562
2563 bar_y += 2;
2564 }
2565 break;
2566 }
2567 }
2568 }
2569
2570 static void
murrine_draw_normal_arrow(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2571 murrine_draw_normal_arrow (cairo_t *cr,
2572 const MurrineRGB *color,
2573 double x, double y, double width, double height)
2574 {
2575 double arrow_width;
2576 double arrow_height;
2577 double line_width_2;
2578
2579 cairo_save (cr);
2580
2581 arrow_width = MIN (height*2.0 + MAX (1.0, ceil (height*2.0/6.0*2.0)/2.0)/2.0, width);
2582 line_width_2 = MAX (1.0, ceil (arrow_width/6.0*2.0)/2.0)/2.0;
2583 arrow_height = arrow_width/2.0+line_width_2;
2584
2585 cairo_translate (cr, x, y-arrow_height/2.0);
2586
2587 cairo_move_to (cr, -arrow_width/2.0, line_width_2);
2588 cairo_line_to (cr, -arrow_width/2.0 + line_width_2, 0);
2589 cairo_arc_negative (cr, 0, arrow_height-2*line_width_2-2*line_width_2*sqrt(2), 2*line_width_2, M_PI_2+M_PI_4, M_PI_4);
2590 cairo_line_to (cr, arrow_width/2.0-line_width_2, 0);
2591 cairo_line_to (cr, arrow_width/2.0, line_width_2);
2592 cairo_line_to (cr, 0, arrow_height);
2593 cairo_close_path (cr);
2594
2595 murrine_set_color_rgb (cr, color);
2596 cairo_fill (cr);
2597
2598 cairo_restore (cr);
2599 }
2600
2601 static void
murrine_draw_normal_arrow_filled(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2602 murrine_draw_normal_arrow_filled (cairo_t *cr,
2603 const MurrineRGB *color,
2604 double x, double y, double width, double height)
2605 {
2606 int arrow_width = width;
2607 int arrow_height = height;
2608 cairo_pattern_t *pat;
2609
2610 cairo_save (cr);
2611
2612 cairo_translate (cr, 0, -0.5);
2613 cairo_move_to (cr, -arrow_width/2, -arrow_height/2);
2614 cairo_line_to (cr, 0, arrow_height/2);
2615 cairo_line_to (cr, arrow_width/2, -arrow_height/2);
2616 cairo_close_path (cr);
2617
2618 pat = cairo_pattern_create_linear (0, -arrow_height/2, 0, arrow_height/2);
2619 murrine_pattern_add_color_stop_rgba (pat, 0.0, color, 0.6);
2620 murrine_pattern_add_color_stop_rgba (pat, 1.0, color, 0.8);
2621 cairo_set_source (cr, pat);
2622 cairo_fill_preserve (cr);
2623 cairo_pattern_destroy (pat);
2624
2625 murrine_set_color_rgb (cr, color);
2626 cairo_stroke (cr);
2627
2628 cairo_restore (cr);
2629 }
2630
2631 static void
murrine_draw_normal_arrow_filled_equilateral(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2632 murrine_draw_normal_arrow_filled_equilateral (cairo_t *cr,
2633 const MurrineRGB *color,
2634 double x, double y, double width, double height)
2635 {
2636 int arrow_width = width+2;
2637 int arrow_height = height;
2638 cairo_pattern_t *pat;
2639
2640 cairo_save (cr);
2641
2642 cairo_translate (cr, 0, -0.5);
2643 cairo_move_to (cr, -arrow_width/2, -arrow_height/2);
2644 cairo_line_to (cr, 0, arrow_height/2);
2645 cairo_line_to (cr, arrow_width/2, -arrow_height/2);
2646 cairo_close_path (cr);
2647
2648 pat = cairo_pattern_create_linear (0, -arrow_height/2, 0, arrow_height/2);
2649 murrine_pattern_add_color_stop_rgba (pat, 0.0, color, 0.6);
2650 murrine_pattern_add_color_stop_rgba (pat, 1.0, color, 0.8);
2651 cairo_set_source (cr, pat);
2652 cairo_fill_preserve (cr);
2653 cairo_pattern_destroy (pat);
2654
2655 murrine_set_color_rgb (cr, color);
2656 cairo_stroke (cr);
2657
2658 cairo_restore (cr);
2659 }
2660
2661 static void
murrine_draw_combo_arrow(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2662 murrine_draw_combo_arrow (cairo_t *cr,
2663 const MurrineRGB *color,
2664 double x, double y, double width, double height)
2665 {
2666 double arrow_width = MIN (height*2/3.0, width);
2667 double arrow_height = arrow_width/2.0;
2668 double gap_size = arrow_height;
2669
2670 cairo_save (cr);
2671 cairo_translate (cr, x, y-(arrow_height+gap_size)/2.0);
2672 cairo_rotate (cr, M_PI);
2673 murrine_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
2674 cairo_restore (cr);
2675
2676 murrine_draw_normal_arrow (cr, color, x, y+(arrow_height+gap_size)/2.0, arrow_width, arrow_height);
2677 }
2678
2679 static void
murrine_draw_combo_arrow_filled(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2680 murrine_draw_combo_arrow_filled (cairo_t *cr,
2681 const MurrineRGB *color,
2682 double x, double y, double width, double height)
2683 {
2684 double arrow_width = 4;
2685 double arrow_height = 5;
2686
2687 cairo_save (cr);
2688 cairo_translate (cr, x, y-5.5);
2689 cairo_rotate (cr, M_PI);
2690 murrine_draw_normal_arrow_filled (cr, color, 0, 0, arrow_width, arrow_height);
2691 cairo_restore (cr);
2692
2693 cairo_translate (cr, x, y+5.5);
2694
2695 murrine_draw_normal_arrow_filled (cr, color, 0, 0, arrow_width, arrow_height);
2696 }
2697
2698 static void
murrine_draw_combo_arrow_filled_equilateral(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2699 murrine_draw_combo_arrow_filled_equilateral (cairo_t *cr,
2700 const MurrineRGB *color,
2701 double x, double y, double width, double height)
2702 {
2703 double arrow_width = 3;
2704 double arrow_height = 3;
2705
2706 cairo_save (cr);
2707 cairo_translate (cr, x-1, y-5.5);
2708 cairo_rotate (cr, M_PI);
2709 murrine_draw_normal_arrow_filled_equilateral (cr, color, 0, 0, arrow_width, arrow_height);
2710 cairo_restore (cr);
2711
2712 cairo_translate (cr, x-1, y+4.5);
2713
2714 murrine_draw_normal_arrow_filled_equilateral (cr, color, 0, 0, arrow_width, arrow_height);
2715 }
2716
2717 static void
_murrine_draw_arrow(cairo_t * cr,const MurrineRGB * color,const ArrowParameters * arrow,double x,double y,double width,double height)2718 _murrine_draw_arrow (cairo_t *cr,
2719 const MurrineRGB *color,
2720 const ArrowParameters *arrow,
2721 double x, double y, double width, double height)
2722 {
2723 double rotate;
2724
2725 switch (arrow->direction)
2726 {
2727 default:
2728 case MRN_DIRECTION_DOWN:
2729 rotate = 0;
2730 break;
2731 case MRN_DIRECTION_UP:
2732 rotate = M_PI;
2733 break;
2734 case MRN_DIRECTION_LEFT:
2735 rotate = M_PI*1.5;
2736 break;
2737 case MRN_DIRECTION_RIGHT:
2738 rotate = M_PI*0.5;
2739 break;
2740 }
2741
2742 if (arrow->type == MRN_ARROW_NORMAL)
2743 {
2744 cairo_translate (cr, x, y);
2745 cairo_rotate (cr, -rotate);
2746 switch (arrow->style)
2747 {
2748 default:
2749 case 0:
2750 murrine_draw_normal_arrow (cr, color, 0, 0, width, height);
2751 break;
2752 case 1:
2753 murrine_draw_normal_arrow_filled (cr, color, 0, 0, width, height);
2754 break;
2755 case 2:
2756 cairo_translate (cr, 0, 1.0);
2757 murrine_draw_normal_arrow_filled_equilateral (cr, color, 1, 1, width-2, height-2);
2758 break;
2759 }
2760 }
2761 else if (arrow->type == MRN_ARROW_COMBO)
2762 {
2763 cairo_translate (cr, x, y);
2764 switch (arrow->style)
2765 {
2766 default:
2767 case 0:
2768 murrine_draw_combo_arrow (cr, color, 0, 0, width, height);
2769 break;
2770 case 1:
2771 murrine_draw_combo_arrow_filled (cr, color, 0, 0, width, height);
2772 break;
2773 case 2:
2774 murrine_draw_combo_arrow_filled_equilateral (cr, color, 1, 1, width-2, height-2);
2775 break;
2776 }
2777 }
2778 }
2779
2780 static void
murrine_draw_arrow(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ArrowParameters * arrow,int x,int y,int width,int height)2781 murrine_draw_arrow (cairo_t *cr,
2782 const MurrineColors *colors,
2783 const WidgetParameters *widget,
2784 const ArrowParameters *arrow,
2785 int x, int y, int width, int height)
2786 {
2787 MurrineRGB color = colors->fg[widget->state_type];
2788 murrine_mix_color (&color, &colors->bg[widget->state_type], 0.2, &color);
2789 gdouble tx, ty;
2790
2791 tx = x+width/2.0;
2792 ty = y+height/2.0;
2793
2794 if (widget->disabled)
2795 {
2796 _murrine_draw_arrow (cr, &colors->shade[0], arrow,
2797 tx+0.5, ty+0.5, width, height);
2798 }
2799
2800 cairo_identity_matrix (cr);
2801
2802 _murrine_draw_arrow (cr, &color, arrow,
2803 tx, ty, width, height);
2804 }
2805
2806 static void
murrine_draw_radiobutton(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height,double trans)2807 murrine_draw_radiobutton (cairo_t *cr,
2808 const MurrineColors *colors,
2809 const WidgetParameters *widget,
2810 const CheckboxParameters *checkbox,
2811 int x, int y, int width, int height,
2812 double trans)
2813 {
2814 const MurrineRGB *border;
2815 const MurrineRGB *dot;
2816 const MurrineRGB *bg = &colors->base[0];
2817 gboolean inconsistent = FALSE;
2818 gboolean draw_box = !checkbox->in_menu;
2819 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2820 int roundness = width+height;
2821 double highlight_shade_new = widget->highlight_shade;
2822 double lightborder_shade_new = widget->lightborder_shade;
2823 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2824
2825 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2826 draw_bullet |= inconsistent;
2827
2828 if (widget->state_type == GTK_STATE_INSENSITIVE)
2829 {
2830 border = &colors->shade[3];
2831 dot = &colors->shade[3];
2832 bg = &colors->bg[0];
2833
2834 mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
2835 mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 3.0);
2836 mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 3.0);
2837 highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2838 lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
2839 }
2840 else
2841 {
2842 border = &colors->shade[5];
2843 if (draw_bullet)
2844 {
2845 border = &colors->spot[2];
2846 bg = &colors->spot[1];
2847 }
2848 dot = &colors->text[widget->state_type];
2849 }
2850
2851 cairo_translate (cr, x, y);
2852
2853 if (draw_box)
2854 {
2855 if (widget->xthickness > 2 && widget->ythickness > 2)
2856 {
2857 if (widget->reliefstyle > 1 && draw_bullet && widget->state_type != GTK_STATE_INSENSITIVE)
2858 {
2859 if (widget->reliefstyle == 5)
2860 murrine_draw_shadow (cr, &widget->parentbg,
2861 0.5, 0.5, width-1, height-1,
2862 roundness+1, widget->corners,
2863 widget->reliefstyle,
2864 mrn_gradient_new, 0.5);
2865 else
2866 {
2867 MurrineRGB shadow;
2868 murrine_shade (border, 0.9, &shadow);
2869
2870 murrine_draw_shadow (cr, &shadow,
2871 0.5, 0.5, width-1, height-1,
2872 roundness+1, widget->corners,
2873 widget->reliefstyle,
2874 mrn_gradient_new, 0.08);
2875 }
2876 }
2877 else if (widget->reliefstyle != 0)
2878 murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, roundness+1, widget->corners);
2879 }
2880
2881 cairo_save (cr);
2882
2883 murrine_rounded_rectangle_closed (cr, 1.5, 1.5, width-3, height-3, roundness, widget->corners);
2884 cairo_clip_preserve (cr);
2885
2886 if (draw_bullet)
2887 {
2888 murrine_draw_glaze (cr, bg,
2889 widget->glow_shade, highlight_shade_new, lightborder_shade_new,
2890 mrn_gradient_new, widget, 2, 2, width-4, height-4,
2891 roundness, widget->corners, TRUE);
2892 }
2893 else
2894 {
2895 murrine_set_color_rgb (cr, bg);
2896 cairo_fill (cr);
2897 }
2898
2899 cairo_restore (cr);
2900
2901 if (checkbox->in_cell)
2902 {
2903 mrn_gradient_new.border_shades[0] = 1.0;
2904 mrn_gradient_new.border_shades[1] = 1.0;
2905 if (!draw_bullet)
2906 mrn_gradient_new.has_border_colors = FALSE;
2907 }
2908 else if (!draw_bullet)
2909 {
2910 mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
2911 mrn_gradient_new.has_border_colors = FALSE;
2912 }
2913
2914 murrine_draw_border (cr, border,
2915 1.5, 1.5, width-3, height-3,
2916 roundness, widget->corners,
2917 mrn_gradient_new, 1.0);
2918 }
2919
2920 if (draw_bullet)
2921 {
2922 if (inconsistent)
2923 {
2924 cairo_save (cr);
2925 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
2926 cairo_set_line_width (cr, 2.0);
2927
2928 cairo_move_to(cr, 5, (double)height/2);
2929 cairo_line_to(cr, width-5, (double)height/2);
2930
2931 murrine_set_color_rgba (cr, dot, trans);
2932 cairo_stroke (cr);
2933 cairo_restore (cr);
2934 }
2935 else
2936 {
2937 if (!draw_box)
2938 {
2939 cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-4, 0, G_PI*2);
2940 }
2941 else
2942 {
2943 MurrineRGB outline;
2944 murrine_invert_text (dot, &outline);
2945
2946 cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-4, 0, G_PI*2);
2947 murrine_set_color_rgba (cr, &outline, 0.3*trans*(widget->state_type == GTK_STATE_INSENSITIVE? 0.2 : 1.0));
2948 cairo_fill (cr);
2949
2950 cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-5, 0, G_PI*2);
2951 }
2952
2953 murrine_set_color_rgba (cr, dot, trans);
2954 cairo_fill (cr);
2955 }
2956 }
2957 }
2958
2959 static void
murrine_draw_checkbox(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height,double trans)2960 murrine_draw_checkbox (cairo_t *cr,
2961 const MurrineColors *colors,
2962 const WidgetParameters *widget,
2963 const CheckboxParameters *checkbox,
2964 int x, int y, int width, int height,
2965 double trans)
2966 {
2967 const MurrineRGB *border;
2968 const MurrineRGB *dot;
2969 const MurrineRGB *bg = &colors->base[0];
2970 gboolean inconsistent = FALSE;
2971 gboolean draw_box = !checkbox->in_menu;
2972 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2973 int roundness = CLAMP (widget->roundness, 0, 2);
2974 double highlight_shade_new = widget->highlight_shade;
2975 double lightborder_shade_new = widget->lightborder_shade;
2976 MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2977
2978 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2979 draw_bullet |= inconsistent;
2980
2981 if (widget->state_type == GTK_STATE_INSENSITIVE)
2982 {
2983 border = &colors->shade[3];
2984 dot = &colors->shade[3];
2985 bg = &colors->bg[0];
2986
2987 mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
2988 mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 3.0);
2989 mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 3.0);
2990 highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2991 lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
2992 }
2993 else
2994 {
2995 border = &colors->shade[5];
2996 if (draw_bullet)
2997 {
2998 border = &colors->spot[2];
2999 bg = &colors->spot[1];
3000 }
3001 dot = &colors->text[widget->state_type];
3002 }
3003
3004 cairo_translate (cr, x, y);
3005
3006 if (draw_box)
3007 {
3008 if (widget->xthickness > 2 && widget->ythickness > 2)
3009 {
3010 if (widget->reliefstyle > 1 && draw_bullet && widget->state_type != GTK_STATE_INSENSITIVE)
3011 {
3012 if (widget->reliefstyle == 5)
3013 murrine_draw_shadow (cr, &widget->parentbg,
3014 0.5, 0.5, width-1, height-1,
3015 roundness+1, widget->corners,
3016 widget->reliefstyle,
3017 mrn_gradient_new, 0.5);
3018 else
3019 {
3020 MurrineRGB shadow;
3021 murrine_shade (border, 0.9, &shadow);
3022
3023 murrine_draw_shadow (cr, &shadow,
3024 0.5, 0.5, width-1, height-1,
3025 roundness+1, widget->corners,
3026 widget->reliefstyle,
3027 mrn_gradient_new, 0.08);
3028 }
3029 }
3030 else if (widget->reliefstyle != 0)
3031 murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, roundness+1, widget->corners);
3032 }
3033
3034 cairo_save (cr);
3035
3036 murrine_rounded_rectangle_closed (cr, 1.5, 1.5, width-3, height-3, roundness, widget->corners);
3037 cairo_clip_preserve (cr);
3038
3039 if (draw_bullet)
3040 {
3041 murrine_draw_glaze (cr, bg,
3042 widget->glow_shade, highlight_shade_new, lightborder_shade_new,
3043 mrn_gradient_new, widget, 2, 2, width-4, height-4,
3044 roundness, widget->corners, TRUE);
3045 }
3046 else
3047 {
3048 murrine_set_color_rgb (cr, bg);
3049 cairo_fill (cr);
3050 }
3051
3052 cairo_restore (cr);
3053
3054 if (checkbox->in_cell)
3055 {
3056 mrn_gradient_new.border_shades[0] = 1.0;
3057 mrn_gradient_new.border_shades[1] = 1.0;
3058 if (!draw_bullet)
3059 mrn_gradient_new.has_border_colors = FALSE;
3060 }
3061 else if (!draw_bullet)
3062 {
3063 mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
3064 mrn_gradient_new.has_border_colors = FALSE;
3065 }
3066
3067 murrine_draw_border (cr, border,
3068 1.5, 1.5, width-3, height-3,
3069 roundness, widget->corners,
3070 mrn_gradient_new, 1.0);
3071 }
3072
3073 if (draw_bullet)
3074 {
3075 if (inconsistent)
3076 {
3077 cairo_save (cr);
3078 cairo_set_line_width (cr, 2.0);
3079 cairo_move_to (cr, 3, (double)height/2);
3080 cairo_line_to (cr, width-3, (double)height/2);
3081 cairo_restore (cr);
3082 }
3083 else
3084 {
3085
3086 if (!draw_box)
3087 {
3088 cairo_scale (cr, (double)width/18.0, (double)height/18.0);
3089 cairo_translate (cr, 2.0, 3.0);
3090 }
3091 else
3092 {
3093 MurrineRGB outline;
3094 murrine_invert_text (dot, &outline);
3095
3096 cairo_scale (cr, (double)width/18.0, (double)height/18.0);
3097
3098 cairo_move_to (cr, 5.0, 5.65);
3099 cairo_line_to (cr, 8.95, 9.57);
3100 cairo_line_to (cr, 16.0, 2.54);
3101 cairo_line_to (cr, 16.0, 8.36);
3102 cairo_line_to (cr, 10.6, 15.1);
3103 cairo_line_to (cr, 7.6, 15.1);
3104 cairo_line_to (cr, 2.95, 10.48);
3105 cairo_line_to (cr, 2.95, 7.65);
3106 cairo_close_path (cr);
3107
3108 murrine_set_color_rgba (cr, &outline, 0.5*trans*(widget->state_type == GTK_STATE_INSENSITIVE ? 0.2 : 1.0));
3109 cairo_fill (cr);
3110
3111 cairo_translate (cr, 4.0, 2.0);
3112 }
3113
3114 cairo_move_to (cr, 0.0, 6.0);
3115 cairo_line_to (cr, 0.0, 8.0);
3116 cairo_line_to (cr, 4.0, 12.0);
3117 cairo_line_to (cr, 6.0, 12.0);
3118 cairo_line_to (cr, 15.0, 1.0);
3119 cairo_line_to (cr, 15.0, 0.0);
3120 cairo_line_to (cr, 14.0, 0.0);
3121 cairo_line_to (cr, 5.0, 9.0);
3122 cairo_line_to (cr, 1.0, 5.0);
3123 cairo_close_path (cr);
3124 }
3125
3126 murrine_set_color_rgba (cr, dot, trans);
3127 cairo_fill (cr);
3128 }
3129 }
3130
3131 static void
murrine_draw_resize_grip(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ResizeGripParameters * grip,int x,int y,int width,int height)3132 murrine_draw_resize_grip (cairo_t *cr,
3133 const MurrineColors *colors,
3134 const WidgetParameters *widget,
3135 const ResizeGripParameters *grip,
3136 int x, int y, int width, int height)
3137 {
3138 const MurrineRGB *dark = &colors->shade[3];
3139 const MurrineRGB *highlight = &colors->shade[0];
3140 int lx, ly;
3141
3142 for (ly=0; ly<4; ly++) /* vertically, four rows of dots */
3143 {
3144 for (lx=0; lx<=ly; lx++) /* horizontally */
3145 {
3146 int ny = (3.5-ly)*3;
3147 int nx = lx*3;
3148
3149 murrine_set_color_rgb (cr, highlight);
3150 cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
3151 cairo_fill (cr);
3152
3153 murrine_set_color_rgb (cr, dark);
3154 cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
3155 cairo_fill (cr);
3156 }
3157 }
3158 }
3159
3160 static void
murrine_draw_expander_arrow(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3161 murrine_draw_expander_arrow (cairo_t *cr,
3162 const MurrineColors *colors,
3163 const WidgetParameters *widget,
3164 const ExpanderParameters *expander,
3165 int x, int y)
3166 {
3167 MurrineRGB color;
3168 cairo_pattern_t *pat;
3169
3170 int diameter;
3171 int offset = (expander->arrowstyle == 2) ? 1 : 0;
3172 double vertical_overshoot;
3173 double radius;
3174 double interp; /* interpolation factor for center position */
3175 double x_double_horz, y_double_horz;
3176 double x_double_vert, y_double_vert;
3177 double x_double, y_double;
3178 gint degrees = 0;
3179 gint line_width = 1;
3180
3181 switch (expander->expander_style)
3182 {
3183 case GTK_EXPANDER_COLLAPSED:
3184 degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 180 : 0;
3185 interp = 0.0;
3186 break;
3187 case GTK_EXPANDER_SEMI_COLLAPSED:
3188 degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 150 : 30;
3189 interp = 0.25;
3190 break;
3191 case GTK_EXPANDER_SEMI_EXPANDED:
3192 degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 120 : 60;
3193 interp = 0.75;
3194 break;
3195 case GTK_EXPANDER_EXPANDED:
3196 degrees = 90;
3197 interp = 1.0;
3198 break;
3199 default:
3200 g_assert_not_reached ();
3201 }
3202
3203 /* Compute distance that the stroke extends beyonds the end
3204 * of the triangle we draw.
3205 */
3206 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3207
3208 /* For odd line widths, we end the vertical line of the triangle
3209 * at a half pixel, so we round differently.
3210 */
3211 if (line_width % 2 == 1)
3212 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3213 else
3214 vertical_overshoot = ceil (vertical_overshoot);
3215
3216 /* Adjust the size of the triangle we draw so that the entire stroke fits
3217 */
3218 diameter = MAX (3, expander->size - 2 * vertical_overshoot);
3219
3220 /* If the line width is odd, we want the diameter to be even,
3221 * and vice versa, so force the sum to be odd. This relationship
3222 * makes the point of the triangle look right.
3223 */
3224 diameter -= (1 - (diameter + line_width) % 2);
3225
3226 radius = diameter / 2. + 4;
3227
3228 /* Adjust the center so that the stroke is properly aligned with
3229 * the pixel grid. The center adjustment is different for the
3230 * horizontal and vertical orientations. For intermediate positions
3231 * we interpolate between the two.
3232 */
3233 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2. + ceil (radius / 8.0);
3234 y_double_vert = y - 0.5;
3235
3236 x_double_horz = x - 0.5 + ceil (radius / 8.0);
3237 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3238
3239 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
3240 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
3241
3242 cairo_translate (cr, x_double, y_double);
3243 cairo_rotate (cr, degrees * G_PI / 180);
3244
3245 cairo_move_to (cr, -radius / 2.0, -radius / 2.0);
3246 cairo_line_to (cr, radius / 2.0 - offset, 0);
3247 cairo_line_to (cr, -radius / 2.0, radius / 2.0);
3248 cairo_close_path (cr);
3249
3250 if (expander->in_treeview)
3251 color = colors->text[widget->state_type];
3252 else
3253 color = colors->fg[widget->state_type];
3254
3255 pat = cairo_pattern_create_linear (-radius/2.0, 0, radius/2.0, 0);
3256 murrine_pattern_add_color_stop_rgba (pat, 0.0, &color, 0.6);
3257 murrine_pattern_add_color_stop_rgba (pat, 1.0, &color, 0.8);
3258 cairo_set_source (cr, pat);
3259 cairo_fill_preserve (cr);
3260 cairo_pattern_destroy (pat);
3261
3262 murrine_set_color_rgb (cr, &color);
3263 cairo_stroke (cr);
3264 }
3265
3266 static void
murrine_draw_expander_circle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3267 murrine_draw_expander_circle (cairo_t *cr,
3268 const MurrineColors *colors,
3269 const WidgetParameters *widget,
3270 const ExpanderParameters *expander,
3271 int x, int y)
3272 {
3273 int expander_size = expander->size;
3274
3275 if (expander_size % 2 != 0)
3276 expander_size--;
3277
3278 cairo_translate (cr, x-expander_size/2, y-expander_size/2);
3279
3280 cairo_arc (cr, expander_size/2.0, expander_size/2.0, expander_size/2.0, 0, G_PI*2);
3281
3282 if (expander->in_treeview)
3283 murrine_set_color_rgb (cr, &colors->text[widget->state_type]);
3284 else
3285 murrine_set_color_rgb (cr, &colors->fg[widget->state_type]);
3286
3287 cairo_fill (cr);
3288
3289 cairo_set_line_width (cr, 2.0);
3290
3291 switch (expander->expander_style)
3292 {
3293 case GTK_EXPANDER_SEMI_COLLAPSED:
3294 case GTK_EXPANDER_COLLAPSED:
3295 cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3296 cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3297 cairo_move_to (cr, (double)expander_size/2, (double)expander_size/2-expander_size/4-0.5);
3298 cairo_line_to (cr, (double)expander_size/2, (double)expander_size/2+expander_size/4+0.5);
3299 break;
3300 case GTK_EXPANDER_SEMI_EXPANDED:
3301 case GTK_EXPANDER_EXPANDED:
3302 cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3303 cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3304 break;
3305 default:
3306 g_assert_not_reached ();
3307 }
3308
3309 if (expander->in_treeview)
3310 murrine_set_color_rgb (cr, &colors->base[widget->state_type]);
3311 else
3312 murrine_set_color_rgb (cr, &colors->bg[widget->state_type]);
3313 cairo_stroke (cr);
3314 }
3315
3316 static void
murrine_draw_expander_button(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3317 murrine_draw_expander_button (cairo_t *cr,
3318 const MurrineColors *colors,
3319 const WidgetParameters *widget,
3320 const ExpanderParameters *expander,
3321 int x, int y)
3322 {
3323 int expander_size = expander->size;
3324
3325 if (expander_size % 2 == 0)
3326 expander_size--;
3327
3328 cairo_translate (cr, x-expander_size/2, y-expander_size/2);
3329
3330 cairo_save (cr);
3331
3332 murrine_rounded_rectangle_closed (cr, 1, 1, expander_size-2, expander_size-2, widget->roundness-1, widget->corners);
3333 cairo_clip_preserve (cr);
3334
3335 murrine_draw_glaze (cr, &colors->bg[widget->state_type],
3336 widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
3337 widget->mrn_gradient, widget, 1, 1, expander_size-2, expander_size-2,
3338 widget->roundness, widget->corners, TRUE);
3339
3340 cairo_restore (cr);
3341
3342 switch (expander->expander_style)
3343 {
3344 case GTK_EXPANDER_SEMI_COLLAPSED:
3345 case GTK_EXPANDER_COLLAPSED:
3346 cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3347 cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3348 cairo_move_to (cr, (double)expander_size/2, (double)expander_size/2-expander_size/4-0.5);
3349 cairo_line_to (cr, (double)expander_size/2, (double)expander_size/2+expander_size/4+0.5);
3350 break;
3351 case GTK_EXPANDER_SEMI_EXPANDED:
3352 case GTK_EXPANDER_EXPANDED:
3353 cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3354 cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3355 break;
3356 default:
3357 g_assert_not_reached ();
3358 }
3359 murrine_set_color_rgb (cr, &colors->fg[widget->state_type]);
3360 cairo_stroke (cr);
3361
3362 murrine_rounded_rectangle (cr, 0.5, 0.5, expander_size-1, expander_size-1, widget->roundness, widget->corners);
3363 murrine_set_color_rgb (cr, &colors->shade[4]);
3364 cairo_stroke (cr);
3365 }
3366
3367 void
murrine_draw_expander(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3368 murrine_draw_expander (cairo_t *cr,
3369 const MurrineColors *colors,
3370 const WidgetParameters *widget,
3371 const ExpanderParameters *expander,
3372 int x, int y)
3373 {
3374 switch (expander->style)
3375 {
3376 default:
3377 case 0:
3378 murrine_draw_expander_arrow (cr, colors, widget, expander, x, y);
3379 break;
3380 case 1:
3381 murrine_draw_expander_circle (cr, colors, widget, expander, x, y);
3382 break;
3383 case 2:
3384 murrine_draw_expander_button (cr, colors, widget, expander, x, y);
3385 break;
3386 }
3387 }
3388
3389 static void
murrine_draw_focus_classic(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3390 murrine_draw_focus_classic (cairo_t *cr,
3391 const MurrineColors *colors,
3392 const WidgetParameters *widget,
3393 const FocusParameters *focus,
3394 int x, int y, int width, int height)
3395 {
3396 cairo_set_line_width (cr, focus->line_width);
3397
3398 if (focus->has_color)
3399 murrine_set_color_rgb (cr, &focus->color);
3400 else if (focus->type == MRN_FOCUS_COLOR_WHEEL_LIGHT)
3401 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
3402 else if (focus->type == MRN_FOCUS_COLOR_WHEEL_DARK)
3403 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
3404 else
3405 murrine_set_color_rgba (cr, &colors->fg[widget->state_type], 0.7);
3406
3407 if (focus->dash_list[0])
3408 {
3409 gint n_dashes = strlen ((gchar *)focus->dash_list);
3410 gdouble *dashes = g_new (gdouble, n_dashes);
3411 gdouble total_length = 0;
3412 gdouble dash_offset;
3413 gint i;
3414
3415 for (i = 0; i < n_dashes; i++)
3416 {
3417 dashes[i] = focus->dash_list[i];
3418 total_length += focus->dash_list[i];
3419 }
3420
3421 dash_offset = -focus->line_width / 2.0;
3422 while (dash_offset < 0)
3423 dash_offset += total_length;
3424
3425 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3426 g_free (dashes);
3427 }
3428
3429 cairo_rectangle (cr, x+focus->line_width/2.0, y+focus->line_width/2.0,
3430 width-focus->line_width, height-focus->line_width);
3431 cairo_stroke (cr);
3432 }
3433
3434 static void
murrine_draw_tab_focus(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3435 murrine_draw_tab_focus (cairo_t *cr,
3436 const MurrineColors *colors,
3437 const WidgetParameters *widget,
3438 const FocusParameters *focus,
3439 int x, int y, int width, int height)
3440 {
3441
3442 }
3443
3444 static void
murrine_draw_focus_border(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3445 murrine_draw_focus_border (cairo_t *cr,
3446 const MurrineColors *colors,
3447 const WidgetParameters *widget,
3448 const FocusParameters *focus,
3449 int x, int y, int width, int height)
3450 {
3451 MurrineRGB fill = focus->color;
3452
3453 /* Default values */
3454 int radius = 0;
3455 double xoffset = 1.0;
3456 double yoffset = 1.0;
3457 double border_alpha = 0.72;
3458 double fill_alpha = 0.18;
3459 double shadow_alpha = 0.36;
3460 boolean focus_fill = TRUE;
3461 boolean focus_border = TRUE;
3462 boolean focus_shadow = FALSE;
3463
3464 /* Do some useful things to adjust focus */
3465 switch (focus->type)
3466 {
3467 case MRN_FOCUS_BUTTON_DEFAULT:
3468 xoffset = -(focus->padding)-2.0;
3469 yoffset = -(focus->padding)-2.0;
3470 radius = widget->roundness;
3471 focus_fill = FALSE;
3472 focus_shadow = TRUE;
3473 border_alpha = 0.2;
3474 shadow_alpha = 0.4;
3475 break;
3476 case MRN_FOCUS_BUTTON:
3477 xoffset = -(focus->padding)-2.0;
3478 yoffset = -(focus->padding)-2.0;
3479 radius = widget->roundness;
3480 focus_fill = FALSE;
3481 focus_shadow = TRUE;
3482 border_alpha = 0.8;
3483 shadow_alpha = 0.4;
3484 break;
3485 case MRN_FOCUS_BUTTON_FLAT:
3486 xoffset = -(focus->padding)-2.0;
3487 yoffset = -(focus->padding)-2.0;
3488 radius = widget->roundness;
3489 break;
3490 case MRN_FOCUS_LABEL:
3491 xoffset = 0.0;
3492 yoffset = 0.0;
3493 radius = widget->roundness;
3494 break;
3495 case MRN_FOCUS_TREEVIEW:
3496 xoffset = -1.0;
3497 yoffset = -1.0;
3498 focus_border = FALSE;
3499 break;
3500 case MRN_FOCUS_TREEVIEW_DND:
3501 radius = widget->roundness;
3502 break;
3503 case MRN_FOCUS_TREEVIEW_HEADER:
3504 cairo_translate (cr, -1, 0);
3505 radius = widget->roundness-1;
3506 break;
3507 case MRN_FOCUS_TREEVIEW_ROW:
3508 if (widget->state_type == GTK_STATE_SELECTED)
3509 {
3510 /* Fallback to classic function, dots */
3511 murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3512 return;
3513 }
3514 xoffset = 1.0;
3515 yoffset = 1.0;
3516 radius = widget->roundness;
3517 break;
3518 case MRN_FOCUS_TAB:
3519 xoffset = CLAMP (-(widget->xthickness)-1.0, -3.0, 0);
3520 yoffset = CLAMP (-(widget->ythickness)-1.0, -3.0, 0);
3521 radius = widget->roundness-1;
3522 focus_border = FALSE;
3523 break;
3524 case MRN_FOCUS_SCALE:
3525 radius = widget->roundness;
3526 break;
3527 case MRN_FOCUS_ICONVIEW:
3528 return;
3529 break;
3530 case MRN_FOCUS_UNKNOWN:
3531 /* Fallback to classic function, dots */
3532 murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3533 return;
3534 break;
3535 default:
3536 break;
3537 };
3538
3539 cairo_translate (cr, x, y);
3540 cairo_set_line_width (cr, focus->line_width);
3541
3542 if (focus_fill)
3543 {
3544 clearlooks_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners);
3545 murrine_set_color_rgba (cr, &fill, fill_alpha);
3546 cairo_fill (cr);
3547 }
3548
3549 if (focus_border)
3550 {
3551 clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, widget->corners);
3552 murrine_set_color_rgba (cr, &fill, border_alpha);
3553 cairo_stroke (cr);
3554 }
3555
3556 if (focus_shadow)
3557 {
3558 clearlooks_rounded_rectangle (cr, xoffset-0.5, yoffset-0.5, width-(xoffset*2)+1, height-(yoffset*2)+1, radius+1, widget->corners);
3559 murrine_set_color_rgba (cr, &fill, shadow_alpha);
3560 cairo_stroke (cr);
3561 }
3562
3563 }
3564
3565 static void
murrine_draw_focus_inner(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3566 murrine_draw_focus_inner (cairo_t *cr,
3567 const MurrineColors *colors,
3568 const WidgetParameters *widget,
3569 const FocusParameters *focus,
3570 int x, int y, int width, int height)
3571 {
3572 MurrineRGB fill = focus->color;
3573
3574 /* Default values */
3575 int radius = 0;
3576 double xoffset = 1.0;
3577 double yoffset = 1.0;
3578 double border_alpha = 0.72;
3579 double fill_alpha = 0.18;
3580 boolean focus_fill = TRUE;
3581 boolean focus_border = TRUE;
3582
3583 /* Do some useful things to adjust focus */
3584 switch (focus->type)
3585 {
3586 case MRN_FOCUS_BUTTON_DEFAULT:
3587 case MRN_FOCUS_BUTTON:
3588 xoffset = -(focus->padding)+1.0;
3589 yoffset = -(focus->padding)+1.0;
3590 radius = widget->roundness-1;
3591 break;
3592 case MRN_FOCUS_BUTTON_FLAT:
3593 xoffset = -(focus->padding)+1.0;
3594 yoffset = -(focus->padding)+1.0;
3595 radius = widget->roundness-1;
3596 break;
3597 case MRN_FOCUS_LABEL:
3598 xoffset = 0.0;
3599 yoffset = 0.0;
3600 radius = widget->roundness;
3601 break;
3602 case MRN_FOCUS_TREEVIEW:
3603 xoffset = -1.0;
3604 yoffset = -1.0;
3605 focus_border = FALSE;
3606 break;
3607 case MRN_FOCUS_TREEVIEW_DND:
3608 radius = widget->roundness;
3609 break;
3610 case MRN_FOCUS_TREEVIEW_HEADER:
3611 cairo_translate (cr, -1, 0);
3612 radius = widget->roundness-1;
3613 break;
3614 case MRN_FOCUS_TREEVIEW_ROW:
3615 if (widget->state_type == GTK_STATE_SELECTED)
3616 {
3617 /* Fallback to classic function, dots */
3618 murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3619 return;
3620 }
3621 xoffset = 1.0;
3622 yoffset = 1.0;
3623 radius = widget->roundness;
3624 break;
3625 case MRN_FOCUS_TAB:
3626 xoffset = 0.0;
3627 yoffset = 0.0;
3628 radius = widget->roundness-1;
3629 break;
3630 case MRN_FOCUS_SCALE:
3631 radius = widget->roundness;
3632 break;
3633 case MRN_FOCUS_ICONVIEW:
3634 return;
3635 break;
3636 case MRN_FOCUS_UNKNOWN:
3637 /* Fallback to classic function, dots */
3638 murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3639 return;
3640 break;
3641 default:
3642 break;
3643 };
3644
3645 cairo_translate (cr, x, y);
3646 cairo_set_line_width (cr, focus->line_width);
3647
3648 if (focus_fill)
3649 {
3650 clearlooks_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners);
3651 murrine_set_color_rgba (cr, &fill, fill_alpha);
3652 cairo_fill (cr);
3653 }
3654
3655 if (focus_border)
3656 {
3657 clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, widget->corners);
3658 murrine_set_color_rgba (cr, &fill, border_alpha);
3659 cairo_stroke (cr);
3660 }
3661 }
3662
3663 void
murrine_draw_focus(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3664 murrine_draw_focus (cairo_t *cr,
3665 const MurrineColors *colors,
3666 const WidgetParameters *widget,
3667 const FocusParameters *focus,
3668 int x, int y, int width, int height)
3669 {
3670 switch (focus->style)
3671 {
3672 default:
3673 case 1:
3674 murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3675 break;
3676 case 2:
3677 murrine_draw_focus_inner (cr, colors, widget, focus, x, y, width, height);
3678 break;
3679 case 3:
3680 murrine_draw_focus_border (cr, colors, widget, focus, x, y, width, height);
3681 break;
3682 }
3683 }
3684
3685 void
murrine_register_style_murrine(MurrineStyleFunctions * functions)3686 murrine_register_style_murrine (MurrineStyleFunctions *functions)
3687 {
3688 g_assert (functions);
3689
3690 functions->draw_button = murrine_draw_button;
3691 functions->draw_combobox = murrine_draw_combobox;
3692 functions->draw_scale_trough = murrine_draw_scale_trough;
3693 functions->draw_progressbar_trough = murrine_draw_progressbar_trough;
3694 functions->draw_progressbar_fill = murrine_draw_progressbar_fill;
3695 functions->draw_entry = murrine_draw_entry;
3696 functions->draw_entry_progress = murrine_draw_entry_progress;
3697 functions->draw_expander = murrine_draw_expander;
3698 functions->draw_slider = murrine_draw_slider;
3699 functions->draw_slider_handle = murrine_draw_slider_handle;
3700 functions->draw_spinbutton = murrine_draw_spinbutton;
3701 functions->draw_spinbutton_down = murrine_draw_spinbutton_down;
3702 functions->draw_optionmenu = murrine_draw_optionmenu;
3703 functions->draw_combo_separator = murrine_draw_combo_separator;
3704 functions->draw_menubar = murrine_draw_menubar;
3705 functions->draw_tab = murrine_draw_tab;
3706 functions->draw_frame = murrine_draw_frame;
3707 functions->draw_separator = murrine_draw_separator;
3708 functions->draw_list_view_header = murrine_draw_list_view_header;
3709 functions->draw_toolbar = murrine_draw_toolbar;
3710 functions->draw_tooltip = murrine_draw_tooltip;
3711 functions->draw_menuitem = murrine_draw_menuitem;
3712 functions->draw_selected_cell = murrine_draw_selected_cell;
3713 functions->draw_scrollbar_stepper = murrine_draw_scrollbar_stepper;
3714 functions->draw_scrollbar_slider = murrine_draw_scrollbar_slider;
3715 functions->draw_scrollbar_trough = murrine_draw_scrollbar_trough;
3716 functions->draw_statusbar = murrine_draw_statusbar;
3717 functions->draw_menu_frame = murrine_draw_menu_frame;
3718 functions->draw_tooltip = murrine_draw_tooltip;
3719 functions->draw_iconview = murrine_draw_iconview;
3720 functions->draw_handle = murrine_draw_handle;
3721 functions->draw_resize_grip = murrine_draw_resize_grip;
3722 functions->draw_arrow = murrine_draw_arrow;
3723 functions->draw_checkbox = murrine_draw_checkbox;
3724 functions->draw_radiobutton = murrine_draw_radiobutton;
3725 functions->draw_focus = murrine_draw_focus;
3726 }
3727