various fixes to MidiRegionView selection handling, key handling, drawing of ghost...
[ardour2.git] / libs / clearlooks-older / clearlooks_style.c
blob074f1604b1a36081c1413b00b8f130b080ce3bb5
1 #include <gtk/gtk.h>
3 #include "clearlooks_style.h"
4 #include "clearlooks_rc_style.h"
5 #include "clearlooks_draw.h"
7 #include <math.h>
8 #include <string.h>
10 #include "bits.c"
11 #include "support.h"
12 //#include "config.h"
14 /* #define DEBUG 1 */
16 #define SCALE_SIZE 5
18 #define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
19 #define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue)
21 #define DRAW_ARGS GtkStyle *style, \
22 GdkWindow *window, \
23 GtkStateType state_type, \
24 GtkShadowType shadow_type, \
25 GdkRectangle *area, \
26 GtkWidget *widget, \
27 const gchar *detail, \
28 gint x, \
29 gint y, \
30 gint width, \
31 gint height
33 static GdkGC *realize_color (GtkStyle * style, GdkColor * color);
34 static GtkStyleClass *parent_class;
35 static GList *progressbars = NULL;
36 static gint8 pboffset = 10;
37 static int timer_id = 0;
39 static void cl_progressbar_remove (gpointer data)
41 if (g_list_find (progressbars, data) == NULL)
42 return;
44 progressbars = g_list_remove (progressbars, data);
45 g_object_unref (data);
47 if (g_list_first(progressbars) == NULL) {
48 g_source_remove(timer_id);
49 timer_id = 0;
53 static void update_progressbar (gpointer data, gpointer user_data)
55 gfloat fraction;
57 if (data == NULL)
58 return;
60 fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (data));
62 /* update only if not filled */
63 if (fraction < 1.0)
64 gtk_widget_queue_resize ((GtkWidget*)data);
66 if (fraction >= 1.0 || GTK_PROGRESS (data)->activity_mode)
67 cl_progressbar_remove (data);
70 static gboolean timer_func (gpointer data)
72 g_list_foreach (progressbars, update_progressbar, NULL);
73 if (--pboffset < 0) pboffset = 9;
74 return (g_list_first(progressbars) != NULL);
77 static gboolean cl_progressbar_known(gconstpointer data)
79 return (g_list_find (progressbars, data) != NULL);
83 static void cl_progressbar_add (gpointer data)
85 if (!GTK_IS_PROGRESS_BAR (data))
86 return;
88 progressbars = g_list_append (progressbars, data);
90 g_object_ref (data);
91 g_signal_connect ((GObject*)data, "unrealize", G_CALLBACK (cl_progressbar_remove), data);
93 if (timer_id == 0)
94 timer_id = g_timeout_add (100, timer_func, NULL);
97 static GdkColor *
98 clearlooks_get_spot_color (ClearlooksRcStyle *clearlooks_rc)
100 GtkRcStyle *rc = GTK_RC_STYLE (clearlooks_rc);
102 if (clearlooks_rc->has_spot_color)
103 return &clearlooks_rc->spot_color;
104 else
105 return &rc->base[GTK_STATE_SELECTED];
108 /**************************************************************************/
110 /* used for optionmenus... */
111 static void
112 draw_tab (GtkStyle *style,
113 GdkWindow *window,
114 GtkStateType state_type,
115 GtkShadowType shadow_type,
116 GdkRectangle *area,
117 GtkWidget *widget,
118 const gchar *detail,
119 gint x,
120 gint y,
121 gint width,
122 gint height)
124 #define ARROW_SPACE 2
125 #define ARROW_LINE_HEIGHT 2
126 #define ARROW_LINE_WIDTH 5
127 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
128 GtkRequisition indicator_size;
129 GtkBorder indicator_spacing;
130 gint arrow_height;
132 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
134 indicator_size.width += (indicator_size.width % 2) - 1;
135 arrow_height = indicator_size.width / 2 + 2;
137 x += (width - indicator_size.width) / 2;
138 y += height/2;
140 if (state_type == GTK_STATE_INSENSITIVE)
142 draw_arrow (window, style->light_gc[state_type], area,
143 GTK_ARROW_UP, 1+x, 1+y-arrow_height,
144 indicator_size.width, arrow_height);
146 draw_arrow (window, style->light_gc[state_type], area,
147 GTK_ARROW_DOWN, 1+x, 1+y+1,
148 indicator_size.width, arrow_height);
151 draw_arrow (window, style->fg_gc[state_type], area,
152 GTK_ARROW_UP, x, y-arrow_height,
153 indicator_size.width, arrow_height);
155 draw_arrow (window, style->fg_gc[state_type], area,
156 GTK_ARROW_DOWN, x, y+1,
157 indicator_size.width, arrow_height);
160 static void
161 clearlooks_draw_arrow (GtkStyle *style,
162 GdkWindow *window,
163 GtkStateType state,
164 GtkShadowType shadow,
165 GdkRectangle *area,
166 GtkWidget *widget,
167 const gchar *detail,
168 GtkArrowType arrow_type,
169 gboolean fill,
170 gint x,
171 gint y,
172 gint width,
173 gint height)
175 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
176 gint original_width, original_x;
177 GdkGC *gc;
179 sanitize_size (window, &width, &height);
181 if (is_combo_box (widget))
183 width = 7;
184 height = 5;
185 x+=2;
186 y+=4;
187 if (state == GTK_STATE_INSENSITIVE)
189 draw_arrow (window, style->light_gc[state], area,
190 GTK_ARROW_UP, 1+x, 1+y-height,
191 width, height);
193 draw_arrow (window, style->light_gc[state], area,
194 GTK_ARROW_DOWN, 1+x, 1+y+1,
195 width, height);
198 draw_arrow (window, style->fg_gc[state], area,
199 GTK_ARROW_UP, x, y-height,
200 width, height);
202 draw_arrow (window, style->fg_gc[state], area,
203 GTK_ARROW_DOWN, x, y+1,
204 width, height);
206 return;
209 original_width = width;
210 original_x = x;
212 /* Make spinbutton arrows and arrows in menus
213 * slightly larger to get the right pixels drawn */
214 if (DETAIL ("spinbutton"))
215 height += 1;
217 if (DETAIL("menuitem"))
219 width = 6;
220 height = 7;
223 /* Compensate arrow position for "sunken" look */
224 if (DETAIL ("spinbutton") && arrow_type == GTK_ARROW_DOWN &&
225 style->xthickness > 2 && style->ythickness > 2)
226 y -= 1;
228 if (widget && widget->parent && GTK_IS_COMBO (widget->parent->parent))
230 width -= 2;
231 height -=2;
232 x++;
235 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
237 if (DETAIL ("menuitem"))
238 x = original_x + original_width - width;
240 if (DETAIL ("spinbutton") && (arrow_type == GTK_ARROW_DOWN))
241 y += 1;
243 if (state == GTK_STATE_INSENSITIVE)
244 draw_arrow (window, style->light_gc[state], area, arrow_type, x + 1, y + 1, width, height);
246 gc = style->fg_gc[state];
248 draw_arrow (window, gc, area, arrow_type, x, y, width, height);
252 static void
253 draw_flat_box (DRAW_ARGS)
255 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
257 g_return_if_fail (GTK_IS_STYLE (style));
258 g_return_if_fail (window != NULL);
260 sanitize_size (window, &width, &height);
262 if (detail &&
263 clearlooks_style->listviewitemstyle == 1 &&
264 state_type == GTK_STATE_SELECTED && (
265 !strncmp ("cell_even", detail, strlen ("cell_even")) ||
266 !strncmp ("cell_odd", detail, strlen ("cell_odd"))))
268 GdkGC *gc;
269 GdkColor lower_color;
270 GdkColor *upper_color;
272 if (GTK_WIDGET_HAS_FOCUS (widget))
274 gc = style->base_gc[state_type];
275 upper_color = &style->base[state_type];
277 else
279 gc = style->base_gc[GTK_STATE_ACTIVE];
280 upper_color = &style->base[GTK_STATE_ACTIVE];
283 if (GTK_IS_TREE_VIEW (widget) && 0)
285 GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
287 if (gtk_tree_selection_count_selected_rows (sel) > 1)
289 parent_class->draw_flat_box (style, window, state_type, shadow_type,
290 area, widget, detail,
291 x, y, width, height);
292 return;
296 shade (upper_color, &lower_color, 0.8);
298 if (area)
299 gdk_gc_set_clip_rectangle (gc, area);
301 draw_hgradient (window, gc, style,
302 x, y, width, height, upper_color, &lower_color);
304 if (area)
305 gdk_gc_set_clip_rectangle (gc, NULL);
307 else
309 parent_class->draw_flat_box (style, window, state_type,
310 shadow_type,
311 area, widget, detail,
312 x, y, width, height);
315 /**************************************************************************/
317 static void
318 draw_shadow (DRAW_ARGS)
320 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
321 CLRectangle r;
323 GdkGC *outer_gc = clearlooks_style->shade_gc[4];
324 GdkGC *gc1 = NULL;
325 GdkGC *gc2 = NULL;
326 gint thickness_light;
327 gint thickness_dark;
328 gboolean interior_focus = FALSE;
330 #if DEBUG
331 printf("draw_shadow: %s %d %d %d %d\n", detail, x, y, width, height);
332 #endif
334 if (widget == NULL)
336 gdk_draw_rectangle (window, outer_gc, FALSE,
337 x, y, width - 1, height - 1);
338 return;
341 if ((width == -1) && (height == -1))
342 gdk_window_get_size (window, &width, &height);
343 else if (width == -1)
344 gdk_window_get_size (window, &width, NULL);
345 else if (height == -1)
346 gdk_window_get_size (window, NULL, &height);
348 cl_rectangle_reset (&r, style);
350 if (DETAIL ("frame") && widget->parent &&
351 GTK_IS_STATUSBAR (widget->parent))
353 gtk_style_apply_default_background (style, window,widget && !GTK_WIDGET_NO_WINDOW (widget),
354 state_type, area, x, y, width, height);
356 if (area)
358 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
359 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
362 gdk_draw_line (window, clearlooks_style->shade_gc[3],
363 x, y, x + width, y);
364 gdk_draw_line (window, clearlooks_style->shade_gc[0],
365 x, y + 1, x + width, y + 1);
367 if (area)
369 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
370 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
373 else if (detail && !strcmp (detail, "entry"))
375 if ( widget->parent && (GTK_IS_COMBO_BOX_ENTRY (widget->parent) ||
376 GTK_IS_SPIN_BUTTON(widget) ||
377 GTK_IS_COMBO (widget->parent)))
379 cl_draw_combobox_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height);
381 else
383 cl_draw_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height);
386 else if (DETAIL ("viewport") || DETAIL ("scrolled_window"))
388 gdk_draw_rectangle (window, clearlooks_style->shade_gc[4], FALSE,
389 x, y, width - 1, height - 1);
391 else
393 if (DETAIL ("menuitem"))
394 outer_gc = clearlooks_style->spot3_gc;
395 else
396 outer_gc = clearlooks_style->shade_gc[4];
398 if (shadow_type == GTK_SHADOW_IN)
399 gdk_draw_rectangle (window, outer_gc, FALSE,
400 x, y, width - 1, height - 1);
401 else if (shadow_type == GTK_SHADOW_OUT)
403 gdk_draw_rectangle (window, outer_gc, FALSE,
404 x, y, width - 1, height - 1);
405 gdk_draw_line (window, style->light_gc[state_type],
406 x+1, y+1, x+width-2, y+1);
407 gdk_draw_line (window, style->light_gc[state_type],
408 x+1, y+1, x+1, y+height-2);
410 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
412 GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3];
413 GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0];
415 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
416 CL_CORNER_NONE, CL_CORNER_NONE);
418 r.bordergc = a;
419 cl_rectangle_set_clip_rectangle (&r, area);
420 cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
421 cl_rectangle_reset_clip_rectangle (&r);
423 r.bordergc = b;
424 cl_rectangle_set_clip_rectangle (&r, area);
425 cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
426 cl_rectangle_reset_clip_rectangle (&r);
428 else if (shadow_type == GTK_SHADOW_ETCHED_IN)
430 GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0];
431 GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3];
433 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
434 CL_CORNER_NONE, CL_CORNER_NONE);
436 r.bordergc = a;
437 cl_rectangle_set_clip_rectangle (&r, area);
438 cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
439 cl_rectangle_reset_clip_rectangle (&r);
441 r.bordergc = b;
442 cl_rectangle_set_clip_rectangle (&r, area);
443 cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
444 cl_rectangle_reset_clip_rectangle (&r);
446 else
447 parent_class->draw_shadow (style, window, state_type, shadow_type,
448 area, widget, detail,
449 x, y, width, height);
453 #define GDK_RECTANGLE_SET(rect,a,b,c,d) rect.x = a; \
454 rect.y = b; \
455 rect.width = c; \
456 rect.height = d;
459 static void
460 draw_box_gap (DRAW_ARGS,
461 GtkPositionType gap_side,
462 gint gap_x,
463 gint gap_width)
465 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
466 CLRectangle r;
468 GdkRegion *area_region = NULL,
469 *gap_region = NULL;
470 GdkRectangle light_rect;
471 GdkRectangle dark_rect;
473 #if DEBUG
474 printf("draw_box_gap: %s %d %d %d %d\n", detail, x, y, width, height);
475 #endif
477 g_return_if_fail (GTK_IS_STYLE (style));
478 g_return_if_fail (window != NULL);
480 sanitize_size (window, &width, &height);
482 cl_rectangle_reset (&r, style);
484 r.bordergc = clearlooks_style->shade_gc[5];
486 r.topleft = style->light_gc[state_type];
487 r.bottomright = clearlooks_style->shade_gc[1];
489 if (area)
490 area_region = gdk_region_rectangle (area);
491 else
493 GdkRectangle tmp = { x, y, width, height };
494 area_region = gdk_region_rectangle (&tmp);
497 switch (gap_side)
499 case GTK_POS_TOP:
501 GdkRectangle rect = { x+gap_x+1, y, gap_width-2, 2 };
502 gap_region = gdk_region_rectangle (&rect);
504 GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y, x+gap_x+1, y+1);
505 GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y, x+gap_x+gap_width-2, y);
507 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
508 CL_CORNER_ROUND, CL_CORNER_ROUND);
510 break;
512 case GTK_POS_BOTTOM:
514 GdkRectangle rect = { x+gap_x+1, y+height-2, gap_width-2, 2 };
515 gap_region = gdk_region_rectangle (&rect);
517 GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y+height-2, x+gap_x+1, y+height-1);
518 GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y+height-2, x+gap_x+gap_width-2, y+height-1);
520 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
521 CL_CORNER_NONE, CL_CORNER_NONE);
523 break;
525 case GTK_POS_LEFT:
527 GdkRectangle rect = { x, y+gap_x+1, 2, gap_width-2 };
528 gap_region = gdk_region_rectangle (&rect);
530 GDK_RECTANGLE_SET (light_rect, x, y+gap_x+1, x+1, y+gap_x+1);
531 GDK_RECTANGLE_SET (dark_rect, x, y+gap_x+gap_width-2, x, y+gap_x+gap_width-2);
533 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND,
534 CL_CORNER_NONE, CL_CORNER_ROUND);
535 break;
537 case GTK_POS_RIGHT:
539 GdkRectangle rect = { x+width-2, y+gap_x+1, 2, gap_width-2 };
540 gap_region = gdk_region_rectangle (&rect);
542 GDK_RECTANGLE_SET (light_rect, x+width-2, y+gap_x+1, x+width-1, y+gap_x+1);
543 GDK_RECTANGLE_SET (dark_rect, x+width-2, y+gap_x+gap_width-2, x+width-1, y+gap_x+gap_width-2);
545 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
546 CL_CORNER_ROUND, CL_CORNER_NONE);
547 break;
551 gdk_region_subtract (area_region, gap_region);
553 gdk_gc_set_clip_region (r.bordergc, area_region);
554 gdk_gc_set_clip_region (r.topleft, area_region);
555 gdk_gc_set_clip_region (r.bottomright, area_region);
557 gdk_region_destroy (area_region);
558 gdk_region_destroy (gap_region);
560 gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, width, height);
562 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
564 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
566 gdk_gc_set_clip_region (r.bordergc, NULL);
567 gdk_gc_set_clip_region (r.topleft, NULL);
568 gdk_gc_set_clip_region (r.bottomright, NULL);
570 /* it's a semi hack */
571 gdk_draw_line (window, style->light_gc[state_type],
572 light_rect.x, light_rect.y,
573 light_rect.width, light_rect.height);
575 gdk_draw_line (window, clearlooks_style->shade_gc[1],
576 dark_rect.x, dark_rect.y,
577 dark_rect.width, dark_rect.height);
580 /**************************************************************************/
582 static void
583 draw_extension (DRAW_ARGS, GtkPositionType gap_side)
585 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
586 int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0;
587 CLRectangle r;
589 #if DEBUG
590 printf("draw_extension: %s %d %d %d %d\n", detail, x, y, width, height);
591 #endif
593 g_return_if_fail (GTK_IS_STYLE (style));
594 g_return_if_fail (window != NULL);
596 sanitize_size (window, &width, &height);
598 if (DETAIL ("tab"))
600 GdkRectangle new_area;
601 GdkColor tmp_color;
603 cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE,
604 CL_CORNER_ROUND, CL_CORNER_ROUND,
605 CL_CORNER_ROUND, CL_CORNER_ROUND);
607 if (state_type == GTK_STATE_ACTIVE)
608 shade (&style->bg[state_type], &tmp_color, 1.08);
609 else
610 shade (&style->bg[state_type], &tmp_color, 1.05);
612 if (area)
614 new_area = *area;
616 else
618 new_area.x = x;
619 new_area.y = y;
620 new_area.width = width;
621 new_area.height = height;
624 switch (gap_side)
626 case GTK_POS_BOTTOM:
627 height+=2;
628 new_area.y = y;
629 new_area.height = height-2;
630 r.gradient_type = CL_GRADIENT_VERTICAL;
631 cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]);
632 cl_rectangle_set_gradient (&r.border_gradient,
633 &clearlooks_style->border[CL_BORDER_UPPER+my_state_type],
634 &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]);
635 break;
636 case GTK_POS_TOP:
637 y-=2;
638 height+=2;
639 new_area.y = y+2;
640 new_area.height = height;
641 r.gradient_type = CL_GRADIENT_VERTICAL;
642 cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color);
643 cl_rectangle_set_gradient (&r.border_gradient,
644 &clearlooks_style->border[CL_BORDER_LOWER+my_state_type],
645 &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]);
646 break;
647 case GTK_POS_LEFT:
648 x-=2;
649 width+=2;
650 new_area.x = x+2;
651 new_area.width = width;
652 r.gradient_type = CL_GRADIENT_HORIZONTAL;
653 cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color);
654 cl_rectangle_set_gradient (&r.border_gradient,
655 &clearlooks_style->border[CL_BORDER_LOWER+my_state_type],
656 &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]);
657 break;
658 case GTK_POS_RIGHT:
659 width+=2;
660 new_area.x = x;
661 new_area.width = width-2;
662 r.gradient_type = CL_GRADIENT_HORIZONTAL;
663 cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]);
664 cl_rectangle_set_gradient (&r.border_gradient,
665 &clearlooks_style->border[CL_BORDER_UPPER+my_state_type],
666 &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]);
667 break;
670 r.topleft = style->light_gc[state_type];
671 r.bottomright = (state_type == GTK_STATE_NORMAL) ? clearlooks_style->shade_gc[1] : NULL;
673 cl_rectangle_set_clip_rectangle (&r, &new_area);
674 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
675 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
676 cl_rectangle_reset_clip_rectangle (&r);
678 /* draw the selection stripe */
679 if (state_type != GTK_STATE_ACTIVE) {
680 cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL);
681 r.fillgc = clearlooks_style->spot2_gc;
683 switch (gap_side)
685 case GTK_POS_BOTTOM:
686 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
687 CL_CORNER_NONE, CL_CORNER_NONE);
688 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2);
689 r.gradient_type = CL_GRADIENT_VERTICAL;
691 cl_rectangle_set_clip_rectangle (&r, &new_area);
692 cl_draw_rectangle (window, widget, style, x, y, width, 3, &r);
693 cl_rectangle_reset_clip_rectangle (&r);
694 break;
695 case GTK_POS_TOP:
696 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
697 CL_CORNER_ROUND, CL_CORNER_ROUND);
698 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3);
699 r.gradient_type = CL_GRADIENT_VERTICAL;
701 cl_rectangle_set_clip_rectangle (&r, &new_area);
702 cl_draw_rectangle (window, widget, style, x, y + height - 3, width, 3, &r);
703 cl_rectangle_reset_clip_rectangle (&r);
704 break;
705 case GTK_POS_LEFT:
706 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND,
707 CL_CORNER_NONE, CL_CORNER_ROUND);
708 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3);
709 r.gradient_type = CL_GRADIENT_HORIZONTAL;
711 cl_rectangle_set_clip_rectangle (&r, &new_area);
712 cl_draw_rectangle (window, widget, style, x + width - 3, y, 3, height, &r);
713 cl_rectangle_reset_clip_rectangle (&r);
714 break;
715 case GTK_POS_RIGHT:
716 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
717 CL_CORNER_ROUND, CL_CORNER_NONE);
718 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2);
719 r.gradient_type = CL_GRADIENT_HORIZONTAL;
721 cl_rectangle_set_clip_rectangle (&r, &new_area);
722 cl_draw_rectangle (window, widget, style, x, y, 3, height, &r);
723 cl_rectangle_reset_clip_rectangle (&r);
724 break;
730 else
732 parent_class->draw_extension (style, window, state_type, shadow_type, area,
733 widget, detail, x, y, width, height,
734 gap_side);
739 /**************************************************************************/
741 static void
742 draw_handle (DRAW_ARGS, GtkOrientation orientation)
744 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
745 gint xx, yy;
746 gint xthick, ythick;
747 GdkGC *light_gc, *dark_gc;
748 GdkRectangle rect;
749 GdkRectangle dest;
750 gint intersect;
751 gint h;
752 int i;
753 int n_lines;
754 int offset;
756 #if DEBUG
757 printf("draw_handle: %s %d %d %d %d\n", detail, x, y, width, height);
758 #endif
760 g_return_if_fail (GTK_IS_STYLE (style));
761 g_return_if_fail (window != NULL);
763 sanitize_size (window, &width, &height);
765 if (state_type == GTK_STATE_PRELIGHT)
766 gtk_style_apply_default_background (style, window,
767 widget && !GTK_WIDGET_NO_WINDOW (widget),
768 state_type, area, x, y, width, height);
770 /* orientation is totally bugged, but this actually works... */
771 orientation = (width > height) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
773 if (!strcmp (detail, "paned"))
775 /* we want to ignore the shadow border in paned widgets */
776 xthick = 0;
777 ythick = 0;
779 else
781 xthick = style->xthickness;
782 ythick = style->ythickness;
785 if ( ((DETAIL ("handlebox") && widget && GTK_IS_HANDLE_BOX (widget)) || DETAIL ("dockitem")) &&
786 orientation == GTK_ORIENTATION_VERTICAL )
788 /* The line in the toolbar */
790 light_gc = style->light_gc[state_type];
791 dark_gc = clearlooks_style->shade_gc[3];
793 if (area)
795 gdk_gc_set_clip_rectangle (light_gc, area);
796 gdk_gc_set_clip_rectangle (dark_gc, area);
799 if (area)
801 gdk_gc_set_clip_rectangle (light_gc, NULL);
802 gdk_gc_set_clip_rectangle (dark_gc, NULL);
805 if (area)
807 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
808 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
811 gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x + width, y);
812 gdk_draw_line (window, clearlooks_style->shade_gc[3], x, y + height - 1, x + width, y + height - 1);
814 if (area)
816 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
817 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
821 light_gc = clearlooks_style->shade_gc[0];
822 dark_gc = clearlooks_style->shade_gc[4];
824 rect.x = x + xthick;
825 rect.y = y + ythick;
826 rect.width = width - (xthick * 2);
827 rect.height = height - (ythick * 2);
829 if (area)
830 intersect = gdk_rectangle_intersect (area, &rect, &dest);
831 else
833 intersect = TRUE;
834 dest = rect;
837 if (!intersect)
838 return;
840 gdk_gc_set_clip_rectangle (light_gc, &dest);
841 gdk_gc_set_clip_rectangle (dark_gc, &dest);
843 n_lines = (!strcmp (detail, "paned")) ? 21 : 11;
845 if (orientation == GTK_ORIENTATION_VERTICAL)
847 h = width - 2 * xthick;
848 h = MAX (3, h - 6);
850 xx = x + (width - h) / 2;
851 offset = (height - 2*ythick - 2*n_lines)/2 + 1;
852 if (offset < 0)
853 offset = 0;
855 for (i = 0, yy = y + ythick + offset; yy <= (y + height - ythick - 1) && i < n_lines; yy += 2, i++)
857 gdk_draw_line (window, dark_gc, xx, yy, xx + h, yy);
858 gdk_draw_line (window, light_gc, xx, yy + 1, xx + h, yy + 1);
861 else
863 h = height - 2 * ythick;
864 h = MAX (3, h - 6);
866 yy = y + (height - h) / 2;
867 offset = (width - 2*xthick - 2*n_lines)/2 + 1;
868 if (offset < 0)
869 offset = 0;
871 for (i = 0, xx = x + xthick + offset; i < n_lines; xx += 2, i++)
873 gdk_draw_line (window, dark_gc, xx, yy, xx, yy + h);
874 gdk_draw_line (window, light_gc, xx + 1, yy, xx + 1, yy + h);
878 gdk_gc_set_clip_rectangle (light_gc, NULL);
879 gdk_gc_set_clip_rectangle (dark_gc, NULL);
882 /**************************************************************************/
884 static void
885 draw_box (DRAW_ARGS)
887 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
888 CLRectangle r;
889 gboolean false_size = FALSE;
891 #ifdef DEBUG
892 printf("draw_box: %s %d %d %d %d\n", detail, x, y, width, height);
893 #endif
895 g_return_if_fail (style != NULL);
896 g_return_if_fail (window != NULL);
898 if (width == -1 || height == -1)
899 false_size = TRUE;
901 if ((width == -1) && (height == -1))
902 gdk_window_get_size (window, &width, &height);
903 else if (width == -1)
904 gdk_window_get_size (window, &width, NULL);
905 else if (height == -1)
906 gdk_window_get_size (window, NULL, &height);
908 cl_rectangle_reset (&r, style);
910 if (widget == NULL)
911 return;
913 /* listview headers */
914 if (widget && DETAIL ("button") && widget->parent &&
915 (GTK_IS_TREE_VIEW(widget->parent) ||
916 GTK_IS_CLIST (widget->parent) ||
917 strcmp(G_OBJECT_TYPE_NAME (widget->parent), "ETree") == 0))
919 cl_draw_treeview_header (style, window, state_type, shadow_type,
920 area, widget, detail, x, y, width, height);
922 else if (detail && (!strcmp (detail, "button") ||
923 !strcmp (detail, "buttondefault")))
925 if (GTK_IS_COMBO_BOX_ENTRY(widget->parent) || GTK_IS_COMBO(widget->parent))
927 cl_draw_combobox_button (style, window, state_type, shadow_type,
928 area, widget,
929 detail, x, y, width, height);
931 else
933 cl_draw_button (style, window, state_type, shadow_type, area, widget,
934 detail, x, y, width, height);
937 else if (detail && (
938 !strcmp (detail, "spinbutton_up") ||
939 !strcmp (detail, "spinbutton_down") ||
940 !strcmp (detail, "spinbutton")))
942 cl_draw_spinbutton (style, window, state_type, shadow_type, area,
943 widget, detail, x, y, width, height);
945 else if (detail && (
946 !strcmp (detail, "hscale") || !strcmp (detail, "vscale")))
948 cl_rectangle_set_button (&r, style, state_type,
949 GTK_WIDGET_HAS_DEFAULT (widget), GTK_WIDGET_HAS_FOCUS (widget),
950 CL_CORNER_ROUND, CL_CORNER_ROUND,
951 CL_CORNER_ROUND, CL_CORNER_ROUND);
953 if (!strcmp (detail, "hscale") || !strcmp (detail, "vscale"))
955 r.fill_gradient.to = &clearlooks_style->shade[2];
956 r.bottomright = clearlooks_style->shade_gc[2];
959 cl_set_corner_sharpness (detail, widget, &r);
961 if (!strcmp (detail, "spinbutton_up"))
963 r.border_gradient.to = r.border_gradient.from;
964 height++;
965 gtk_style_apply_default_background (style, window, FALSE, state_type,
966 area, x, y, width, height);
968 else if (!strcmp (detail, "spinbutton_down"))
970 r.border_gradient.to = r.border_gradient.from;
971 gtk_style_apply_default_background (style, window, FALSE, state_type,
972 area, x, y, width, height);
975 cl_rectangle_set_clip_rectangle (&r, area);
976 cl_draw_rectangle (window, widget, style, x+1, y+1, width-2, height-2, &r);
977 cl_draw_shadow (window, widget, style, x+1, y+1, width-2, height-2, &r);
978 cl_rectangle_reset_clip_rectangle (&r);
980 else if (DETAIL ("trough") && GTK_IS_PROGRESS_BAR (widget))
982 GdkPoint points[4] = { {x,y}, {x+width-1,y}, {x,y+height-1}, {x+width-1,y+height-1} };
984 gdk_draw_points (window, style->bg_gc[state_type], points, 4);
986 r.bordergc = clearlooks_style->shade_gc[5];
987 r.fillgc = clearlooks_style->shade_gc[2];
989 cl_rectangle_set_corners (&r, CL_CORNER_NARROW, CL_CORNER_NARROW,
990 CL_CORNER_NARROW, CL_CORNER_NARROW);
992 cl_rectangle_set_clip_rectangle (&r, area);
993 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
994 cl_rectangle_reset_clip_rectangle (&r);
996 else if (DETAIL ("trough") &&
997 (GTK_IS_VSCALE (widget) || GTK_IS_HSCALE (widget)))
999 GdkGC *inner = clearlooks_style->shade_gc[3],
1000 *outer = clearlooks_style->shade_gc[5],
1001 *shadow = clearlooks_style->shade_gc[4];
1002 GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)),
1003 lower_color;
1005 GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
1007 GtkOrientation orientation = GTK_RANGE (widget)->orientation;
1009 gint fill_size = (orientation ? height : width) *
1010 (1 / ((adjustment->upper - adjustment->lower) /
1011 (adjustment->value - adjustment->lower)));
1013 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1015 y += (height - SCALE_SIZE) / 2;
1016 height = SCALE_SIZE;
1018 else
1020 x += (width - SCALE_SIZE) / 2;
1021 width = SCALE_SIZE;
1024 if (state_type == GTK_STATE_INSENSITIVE)
1026 outer = clearlooks_style->shade_gc[4];
1027 inner = clearlooks_style->shade_gc[2];
1028 shadow = clearlooks_style->shade_gc[3];
1031 cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE,
1032 CL_CORNER_NONE, CL_CORNER_NONE );
1034 r.topleft = shadow;
1036 cl_rectangle_set_clip_rectangle (&r, area);
1037 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1038 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1039 cl_rectangle_reset_clip_rectangle (&r);
1041 /* DRAW FILL */
1042 shade (&upper_color, &lower_color, 1.3);
1044 r.bordergc = clearlooks_style->spot3_gc;
1045 r.fillgc = style->bg_gc[state_type];
1047 r.gradient_type = (orientation == GTK_ORIENTATION_HORIZONTAL ) ? CL_GRADIENT_VERTICAL
1048 : CL_GRADIENT_HORIZONTAL;
1050 cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color);
1052 cl_rectangle_set_clip_rectangle (&r, area);
1053 if (orientation == GTK_ORIENTATION_HORIZONTAL && fill_size > 1)
1055 if (gtk_range_get_inverted(GTK_RANGE(widget)) != (get_direction(widget) == GTK_TEXT_DIR_RTL))
1056 cl_draw_rectangle (window, widget, style, x+width-fill_size, y, fill_size, height, &r);
1057 else
1058 cl_draw_rectangle (window, widget, style, x, y, fill_size, height, &r);
1060 else if (fill_size > 1)
1062 if (gtk_range_get_inverted (GTK_RANGE (widget)))
1063 cl_draw_rectangle (window, widget, style, x, y+height-fill_size, width, fill_size, &r);
1064 else
1065 cl_draw_rectangle (window, widget, style, x, y, width, fill_size, &r);
1067 cl_rectangle_reset_clip_rectangle (&r);
1069 else if (DETAIL ("trough"))
1071 GdkGC *inner = clearlooks_style->shade_gc[3],
1072 *outer = clearlooks_style->shade_gc[5];
1074 cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE,
1075 CL_CORNER_NONE, CL_CORNER_NONE );
1077 if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_VERTICAL)
1079 y+=1;
1080 height-=2;
1082 else
1084 x+=1;
1085 width-=2;
1088 cl_rectangle_set_clip_rectangle (&r, area);
1089 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1090 cl_rectangle_reset_clip_rectangle (&r);
1092 else if (detail && (!strcmp (detail, "vscrollbar") ||
1093 !strcmp (detail, "hscrollbar") ||
1094 !strcmp (detail, "stepper")))
1096 ClScrollButtonType button_type = CL_SCROLLBUTTON_OTHER;
1097 gboolean horizontal = TRUE;
1099 if (GTK_IS_VSCROLLBAR(widget))
1101 if (y == widget->allocation.y)
1102 button_type = CL_SCROLLBUTTON_BEGIN;
1103 else if (y+height == widget->allocation.y+widget->allocation.height)
1104 button_type = CL_SCROLLBUTTON_END;
1106 horizontal = FALSE;
1108 else if (GTK_IS_HSCROLLBAR(widget))
1110 if (x == widget->allocation.x)
1111 button_type = CL_SCROLLBUTTON_BEGIN;
1112 else if (x+width == widget->allocation.x+widget->allocation.width)
1113 button_type = CL_SCROLLBUTTON_END;
1116 cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, 0,0,0,0);
1118 cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL);
1119 cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type],
1120 &clearlooks_style->inset_dark[state_type]);
1123 r.gradient_type = horizontal ? CL_GRADIENT_VERTICAL
1124 : CL_GRADIENT_HORIZONTAL;
1126 r.bottomright = clearlooks_style->shade_gc[1];
1127 r.border_gradient.to = r.border_gradient.from;
1129 if (button_type == CL_SCROLLBUTTON_OTHER)
1131 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1132 CL_CORNER_NONE, CL_CORNER_NONE);
1134 else if (button_type == CL_SCROLLBUTTON_BEGIN)
1136 if (horizontal)
1137 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE,
1138 CL_CORNER_ROUND, CL_CORNER_NONE);
1139 else
1140 cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND,
1141 CL_CORNER_NONE, CL_CORNER_NONE);
1143 else
1145 if (horizontal)
1146 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND,
1147 CL_CORNER_NONE, CL_CORNER_ROUND);
1148 else
1149 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1150 CL_CORNER_ROUND, CL_CORNER_ROUND);
1153 cl_rectangle_set_clip_rectangle (&r, area);
1154 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1155 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1156 cl_rectangle_reset_clip_rectangle (&r);
1159 else if (DETAIL ("slider"))
1161 if (DETAIL("slider") && widget && GTK_IS_RANGE (widget))
1163 GtkAdjustment *adj = GTK_RANGE (widget)->adjustment;
1165 if (adj->value <= adj->lower &&
1166 (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b))
1168 if (GTK_IS_VSCROLLBAR (widget))
1170 y-=1;
1171 height+=1;
1173 else if (GTK_IS_HSCROLLBAR (widget))
1175 x-=1;
1176 width+=1;
1179 if (adj->value >= adj->upper - adj->page_size &&
1180 (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d))
1182 if (GTK_IS_VSCROLLBAR (widget))
1183 height+=1;
1184 else if (GTK_IS_HSCROLLBAR (widget))
1185 width+=1;
1189 cl_rectangle_set_button (&r, style, state_type, FALSE, GTK_WIDGET_HAS_FOCUS (widget),
1190 CL_CORNER_NONE, CL_CORNER_NONE,
1191 CL_CORNER_NONE, CL_CORNER_NONE);
1193 r.gradient_type = GTK_IS_HSCROLLBAR (widget) ? CL_GRADIENT_VERTICAL
1194 : CL_GRADIENT_HORIZONTAL;
1196 cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type],
1197 &clearlooks_style->inset_dark[state_type]);
1199 r.bottomright = clearlooks_style->shade_gc[1];
1200 r.border_gradient.to = r.border_gradient.from;
1202 cl_rectangle_set_clip_rectangle (&r, area);
1203 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1204 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1205 cl_rectangle_reset_clip_rectangle (&r);
1207 else if (detail && !strcmp (detail, "optionmenu")) /* supporting deprecated */
1209 cl_draw_optionmenu(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
1211 else if (DETAIL ("menuitem"))
1213 if (clearlooks_style->menuitemstyle == 0)
1215 cl_draw_menuitem_flat (window, widget, style, area, state_type,
1216 x, y, width, height, &r);
1218 else if (clearlooks_style->menuitemstyle == 1)
1220 cl_draw_menuitem_gradient (window, widget, style, area, state_type,
1221 x, y, width, height, &r);
1223 else
1225 cl_draw_menuitem_button (window, widget, style, area, state_type,
1226 x, y, width, height, &r);
1229 else if (DETAIL ("menubar") && (clearlooks_style->sunkenmenubar || clearlooks_style->menubarstyle > 0))
1231 GdkGC *dark = clearlooks_style->shade_gc[2];
1232 GdkColor upper_color, lower_color;
1234 /* don't draw sunken menubar on gnome panel
1235 IT'S A HACK! HORRIBLE HACK! HIDEOUS HACK!
1236 BUT IT WORKS FOR ME(tm)! */
1237 if (widget->parent &&
1238 strcmp(G_OBJECT_TYPE_NAME (widget->parent), "PanelWidget") == 0)
1239 return;
1241 shade(&style->bg[state_type], &upper_color, 1.0);
1242 shade(&style->bg[state_type], &lower_color, 0.95);
1244 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1245 CL_CORNER_NONE, CL_CORNER_NONE);
1247 r.fillgc = style->bg_gc[state_type];
1248 r.bordergc = clearlooks_style->shade_gc[2];
1249 r.gradient_type = CL_GRADIENT_VERTICAL;
1251 cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->shade[2],
1252 &clearlooks_style->shade[3]);
1253 cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color);
1255 /* make vertical and top borders invisible for style 2 */
1256 if (clearlooks_style->menubarstyle == 2) {
1257 x--; width+=2;
1258 y--; height+=1;
1261 cl_rectangle_set_clip_rectangle (&r, area);
1262 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1263 cl_rectangle_reset_clip_rectangle (&r);
1265 else if (DETAIL ("menu") && widget->parent &&
1266 GDK_IS_WINDOW (widget->parent->window))
1268 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1269 CL_CORNER_NONE, CL_CORNER_NONE);
1271 r.bordergc = clearlooks_style->border_gc[CL_BORDER_UPPER];
1272 r.topleft = style->light_gc[state_type];
1273 r.bottomright = clearlooks_style->shade_gc[1];
1275 cl_rectangle_set_clip_rectangle (&r, area);
1276 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1277 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1278 cl_rectangle_reset_clip_rectangle (&r);
1280 return;
1282 else if (DETAIL ("bar") && widget && GTK_IS_PROGRESS_BAR (widget))
1284 GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)),
1285 lower_color,
1286 prev_foreground;
1287 gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode;
1289 #ifdef HAVE_ANIMATION
1290 if (!activity_mode && gtk_progress_bar_get_fraction (widget) != 1.0 &&
1291 !cl_progressbar_known((gconstpointer)widget))
1293 cl_progressbar_add ((gpointer)widget);
1295 #endif
1296 cl_progressbar_fill (window, widget, style, style->black_gc,
1297 x, y, width, height,
1298 #ifdef HAVE_ANIMATION
1299 activity_mode ? 0 : pboffset,
1300 #else
1302 #endif
1303 area);
1305 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1306 CL_CORNER_NONE, CL_CORNER_NONE);
1308 r.bordergc = clearlooks_style->spot3_gc;
1309 r.topleft = clearlooks_style->spot2_gc;
1311 prev_foreground = cl_gc_set_fg_color_shade (clearlooks_style->spot2_gc,
1312 style->colormap,
1313 &clearlooks_style->spot2,
1314 1.2);
1316 cl_rectangle_set_clip_rectangle (&r, area);
1317 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1318 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1319 cl_rectangle_reset_clip_rectangle (&r);
1321 gdk_gc_set_foreground (clearlooks_style->spot2_gc, &prev_foreground);
1324 else if ( widget && (DETAIL ("menubar") || DETAIL ("toolbar") || DETAIL ("dockitem_bin") || DETAIL ("handlebox_bin")) && shadow_type != GTK_SHADOW_NONE) /* Toolbars and menus */
1326 if (area)
1328 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area);
1329 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area);
1332 gtk_style_apply_default_background (style, window,
1333 widget && !GTK_WIDGET_NO_WINDOW (widget),
1334 state_type, area, x, y, width, height);
1336 /* we only want the borders on horizontal toolbars */
1337 if ( DETAIL ("menubar") || height < 2*width ) {
1338 if (!DETAIL ("menubar"))
1339 gdk_draw_line (window, clearlooks_style->shade_gc[0],
1340 x, y, x + width, y); /* top */
1342 gdk_draw_line (window, clearlooks_style->shade_gc[3],
1343 x, y + height - 1, x + width, y + height - 1); /* bottom */
1346 if (area)
1348 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL);
1349 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL);
1352 else
1354 parent_class->draw_box (style, window, state_type, shadow_type, area,
1355 widget, detail, x, y, width, height);
1359 /**************************************************************************/
1361 static void
1362 ensure_check_pixmaps (GtkStyle *style,
1363 GtkStateType state,
1364 GdkScreen *screen,
1365 gboolean treeview)
1367 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1368 ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style);
1369 GdkPixbuf *check, *base, *inconsistent, *composite;
1370 GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc);
1372 if (clearlooks_style->check_pixmap_nonactive[state] != NULL)
1373 return;
1375 if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) {
1376 check = generate_bit (check_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1377 inconsistent = generate_bit (check_inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1378 } else {
1379 check = generate_bit (check_alpha, &style->text[state], 1.0);
1380 inconsistent = generate_bit (check_inconsistent_alpha, &style->text[state], 1.0);
1383 if (state == GTK_STATE_ACTIVE && !treeview)
1384 base = generate_bit (check_base_alpha, &style->bg[state], 1.0);
1385 else
1386 base = generate_bit (check_base_alpha, &style->base[GTK_STATE_NORMAL], 1.0);
1388 if (treeview)
1389 composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0);
1390 else
1391 composite = generate_bit (NULL, &clearlooks_style->shade[5], 1.0);
1393 gdk_pixbuf_composite (base, composite,
1394 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1395 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1397 clearlooks_style->check_pixmap_nonactive[state] =
1398 pixbuf_to_pixmap (style, composite, screen);
1400 gdk_pixbuf_composite (check, composite,
1401 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1402 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1404 clearlooks_style->check_pixmap_active[state] =
1405 pixbuf_to_pixmap (style, composite, screen);
1407 g_object_unref (composite);
1409 composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0);
1411 gdk_pixbuf_composite (base, composite,
1412 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1413 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1415 gdk_pixbuf_composite (inconsistent, composite,
1416 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1417 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1419 clearlooks_style->check_pixmap_inconsistent[state] =
1420 pixbuf_to_pixmap (style, composite, screen);
1422 g_object_unref (composite);
1423 g_object_unref (base);
1424 g_object_unref (check);
1425 g_object_unref (inconsistent);
1428 static void
1429 draw_check (DRAW_ARGS)
1431 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1432 GdkGC *gc = style->base_gc[state_type];
1433 GdkPixmap *pixmap;
1434 gboolean treeview;
1436 if (DETAIL ("check")) /* Menu item */
1438 parent_class->draw_check (style, window, state_type, shadow_type, area,
1439 widget, detail, x, y, width, height);
1440 return;
1443 treeview = widget && GTK_IS_TREE_VIEW(widget);
1444 ensure_check_pixmaps (style, state_type, gtk_widget_get_screen (widget), treeview);
1446 if (area)
1447 gdk_gc_set_clip_rectangle (gc, area);
1449 if (shadow_type == GTK_SHADOW_IN)
1450 pixmap = clearlooks_style->check_pixmap_active[state_type];
1451 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
1452 pixmap = clearlooks_style->check_pixmap_inconsistent[state_type];
1453 else
1454 pixmap = clearlooks_style->check_pixmap_nonactive[state_type];
1456 x += (width - CHECK_SIZE)/2;
1457 y += (height - CHECK_SIZE)/2;
1459 gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, CHECK_SIZE, CHECK_SIZE);
1461 if (area)
1462 gdk_gc_set_clip_rectangle (gc, NULL);
1465 /**************************************************************************/
1466 static void
1467 draw_slider (DRAW_ARGS, GtkOrientation orientation)
1469 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1470 GdkGC *shade_gc = clearlooks_style->shade_gc[4];
1471 GdkGC *white_gc = clearlooks_style->shade_gc[0];
1472 int x1, y1;
1474 #if DEBUG
1475 printf("draw_slider: %s %d %d %d %d\n", detail, x, y, width, height);
1476 #endif
1478 g_return_if_fail (GTK_IS_STYLE (style));
1479 g_return_if_fail (window != NULL);
1481 sanitize_size (window, &width, &height);
1483 gtk_paint_box (style, window, state_type, shadow_type,
1484 area, widget, detail, x, y, width, height);
1486 if ((orientation == GTK_ORIENTATION_VERTICAL && height < 20) ||
1487 (orientation == GTK_ORIENTATION_HORIZONTAL && width < 20))
1488 return;
1490 if (detail && strcmp ("slider", detail) == 0)
1492 if (area)
1494 gdk_gc_set_clip_rectangle (shade_gc, area);
1495 gdk_gc_set_clip_rectangle (white_gc, area);
1497 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1499 x1 = x + width / 2 - 4;
1500 y1 = y + (height - 6) / 2;
1501 gdk_draw_line (window, shade_gc, x1, y1, x1, y1 + 6);
1502 gdk_draw_line (window, white_gc, x1 + 1, y1, x1 + 1, y1 + 6);
1503 gdk_draw_line (window, shade_gc, x1 + 3, y1, x1 + 3, y1 + 6);
1504 gdk_draw_line (window, white_gc, x1 + 3 + 1, y1, x1 + 3 + 1, y1 + 6);
1505 gdk_draw_line (window, shade_gc, x1 + 3*2, y1, x1 + 3*2, y1 + 6);
1506 gdk_draw_line (window, white_gc, x1 + 3*2 + 1, y1, x1 + 3*2 + 1, y1 + 6);
1508 else
1510 x1 = x + (width - 6) / 2;
1511 y1 = y + height / 2 - 4;
1512 gdk_draw_line (window, shade_gc, x1 + 6, y1, x1, y1);
1513 gdk_draw_line (window, white_gc, x1 + 6, y1 + 1, x1, y1 + 1);
1514 gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3, x1, y1 + 3);
1515 gdk_draw_line (window, white_gc, x1 + 6, y1 + 3 + 1, x1, y1 + 3 + 1);
1516 gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3*2, x1, y1 + 3*2);
1517 gdk_draw_line (window, white_gc, x1 + 6, y1 + 3*2 + 1, x1, y1 + 3*2 + 1);
1519 if (area)
1521 gdk_gc_set_clip_rectangle (shade_gc, NULL);
1522 gdk_gc_set_clip_rectangle (white_gc, NULL);
1525 else if (detail && (strcmp ("hscale", detail) == 0 || strcmp ("vscale", detail) == 0))
1527 if (area)
1529 gdk_gc_set_clip_rectangle (shade_gc, area);
1530 gdk_gc_set_clip_rectangle (white_gc, area);
1533 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1535 x1 = x + width / 2 - 3;
1536 y1 = y + (height - 7) / 2;
1537 gdk_draw_line (window, shade_gc, x1 + 0, y1 + 5, x1 + 0, y1 + 1);
1538 gdk_draw_line (window, white_gc, x1 + 1, y1 + 5, x1 + 1, y1 + 1);
1539 gdk_draw_line (window, shade_gc, x1 + 3, y1 + 5, x1 + 3, y1 + 1);
1540 gdk_draw_line (window, white_gc, x1 + 4, y1 + 5, x1 + 4, y1 + 1);
1541 gdk_draw_line (window, shade_gc, x1 + 6, y1 + 5, x1 + 6, y1 + 1);
1542 gdk_draw_line (window, white_gc, x1 + 7, y1 + 5, x1 + 7, y1 + 1);
1544 else
1546 x1 = x + (width - 7) / 2;
1547 y1 = y + height / 2 - 3;
1548 gdk_draw_line (window, shade_gc, x1 + 5, y1 + 0, x1 + 1, y1 + 0);
1549 gdk_draw_line (window, white_gc, x1 + 5, y1 + 1, x1 + 1, y1 + 1);
1550 gdk_draw_line (window, shade_gc, x1 + 5, y1 + 3, x1 + 1, y1 + 3);
1551 gdk_draw_line (window, white_gc, x1 + 5, y1 + 4, x1 + 1, y1 + 4);
1552 gdk_draw_line (window, shade_gc, x1 + 5, y1 + 6, x1 + 1, y1 + 6);
1553 gdk_draw_line (window, white_gc, x1 + 5, y1 + 7, x1 + 1, y1 + 7);
1555 if (area)
1557 gdk_gc_set_clip_rectangle (shade_gc, NULL);
1558 gdk_gc_set_clip_rectangle (white_gc, NULL);
1563 /**************************************************************************/
1564 static void
1565 ensure_radio_pixmaps (GtkStyle *style,
1566 GtkStateType state,
1567 GdkScreen *screen)
1569 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1570 ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style);
1571 GdkPixbuf *dot, *circle, *outline, *inconsistent, *composite;
1572 GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc);
1573 GdkColor *composite_color;
1575 if (clearlooks_style->radio_pixmap_nonactive[state] != NULL)
1576 return;
1578 if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) {
1579 dot = colorize_bit (dot_intensity, dot_alpha, &style->text[GTK_STATE_NORMAL]);
1580 inconsistent = generate_bit (inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0);
1581 } else {
1582 dot = colorize_bit (dot_intensity, dot_alpha, &style->text[state]);
1583 inconsistent = generate_bit (inconsistent_alpha, &style->text[state], 1.0);
1586 outline = generate_bit (outline_alpha, &clearlooks_style->shade[5], 1.0);
1588 if (clearlooks_style->radio_pixmap_mask == NULL)
1590 gdk_pixbuf_render_pixmap_and_mask (outline,
1591 NULL,
1592 &clearlooks_style->radio_pixmap_mask,
1596 if (state == GTK_STATE_ACTIVE)
1598 composite_color = &style->bg[GTK_STATE_PRELIGHT];
1599 circle = generate_bit (circle_alpha, &style->bg[state], 1.0);
1601 else
1603 composite_color = &style->bg[state];
1604 circle = generate_bit (circle_alpha, &style->base[GTK_STATE_NORMAL], 1.0);
1607 composite = generate_bit (NULL, composite_color, 1.0);
1609 gdk_pixbuf_composite (outline, composite,
1610 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1611 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1613 gdk_pixbuf_composite (circle, composite,
1614 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1615 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1617 clearlooks_style->radio_pixmap_nonactive[state] =
1618 pixbuf_to_pixmap (style, composite, screen);
1620 gdk_pixbuf_composite (dot, composite,
1621 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1622 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1624 clearlooks_style->radio_pixmap_active[state] =
1625 pixbuf_to_pixmap (style, composite, screen);
1627 g_object_unref (composite);
1629 composite = generate_bit (NULL, composite_color,1.0);
1631 gdk_pixbuf_composite (outline, composite,
1632 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1633 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1634 gdk_pixbuf_composite (circle, composite,
1635 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1636 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1637 gdk_pixbuf_composite (inconsistent, composite,
1638 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0,
1639 1.0, 1.0, GDK_INTERP_NEAREST, 255);
1641 clearlooks_style->radio_pixmap_inconsistent[state] =
1642 pixbuf_to_pixmap (style, composite, screen);
1644 g_object_unref (composite);
1645 g_object_unref (circle);
1646 g_object_unref (dot);
1647 g_object_unref (inconsistent);
1648 g_object_unref (outline);
1651 static void
1652 draw_option (DRAW_ARGS)
1654 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1655 GdkGC *gc = style->base_gc[state_type];
1656 GdkPixmap *pixmap;
1658 if (DETAIL ("option")) /* Menu item */
1660 parent_class->draw_option (style, window, state_type, shadow_type,
1661 area, widget, detail, x, y, width, height);
1662 return;
1665 ensure_radio_pixmaps (style, state_type, gtk_widget_get_screen (widget));
1667 if (area)
1668 gdk_gc_set_clip_rectangle (gc, area);
1670 if (shadow_type == GTK_SHADOW_IN)
1671 pixmap = clearlooks_style->radio_pixmap_active[state_type];
1672 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
1673 pixmap = clearlooks_style->radio_pixmap_inconsistent[state_type];
1674 else
1675 pixmap = clearlooks_style->radio_pixmap_nonactive[state_type];
1677 x += (width - RADIO_SIZE)/2;
1678 y += (height - RADIO_SIZE)/2;
1680 #ifndef GTKOSX
1681 gdk_gc_set_clip_mask (gc, clearlooks_style->radio_pixmap_mask);
1682 gdk_gc_set_clip_origin (gc, x, y);
1683 #endif
1685 gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y,
1686 RADIO_SIZE, RADIO_SIZE);
1688 #ifndef GTKOSX
1689 gdk_gc_set_clip_origin (gc, 0, 0);
1690 gdk_gc_set_clip_mask (gc, NULL);
1691 #endif
1693 if (area)
1694 gdk_gc_set_clip_rectangle (gc, NULL);
1697 /**************************************************************************/
1699 static void
1700 draw_shadow_gap (DRAW_ARGS,
1701 GtkPositionType gap_side,
1702 gint gap_x,
1703 gint gap_width)
1705 /* I need to improve this function. */
1706 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1707 CLRectangle r;
1708 GdkRegion *area_region = NULL,
1709 *gap_region = NULL;
1711 #if DEBUG
1712 printf("draw_shadow_gap: %s %d %d %d %d\n", detail, x, y, width, height);
1713 #endif
1715 g_return_if_fail (GTK_IS_STYLE (style));
1716 g_return_if_fail (window != NULL);
1718 sanitize_size (window, &width, &height);
1720 cl_rectangle_reset (&r, style);
1721 cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE,
1722 CL_CORNER_NONE, CL_CORNER_NONE);
1724 if (area)
1726 area_region = gdk_region_rectangle (area);
1728 switch (gap_side)
1730 case GTK_POS_TOP:
1732 GdkRectangle rect = { x+gap_x, y, gap_width, 2 };
1733 gap_region = gdk_region_rectangle (&rect);
1734 break;
1736 case GTK_POS_BOTTOM:
1738 GdkRectangle rect = { x+gap_x, y+height-2, gap_width, 2 };
1739 gap_region = gdk_region_rectangle (&rect);
1740 break;
1742 case GTK_POS_LEFT:
1744 GdkRectangle rect = { x, y+gap_x, 2, gap_width };
1745 gap_region = gdk_region_rectangle (&rect);
1746 break;
1748 case GTK_POS_RIGHT:
1750 GdkRectangle rect = { x+width-2, y+gap_x, 2, gap_width };
1751 gap_region = gdk_region_rectangle (&rect);
1752 break;
1756 gdk_region_subtract (area_region, gap_region);
1759 if (shadow_type == GTK_SHADOW_ETCHED_IN ||
1760 shadow_type == GTK_SHADOW_ETCHED_OUT)
1762 GdkGC *a;
1763 GdkGC *b;
1765 if (shadow_type == GTK_SHADOW_ETCHED_IN)
1767 a = style->light_gc[state_type];
1768 b = clearlooks_style->shade_gc[3];
1770 else
1772 a = clearlooks_style->shade_gc[3];
1773 b = style->light_gc[state_type];
1776 gdk_gc_set_clip_region (a, area_region);
1777 gdk_gc_set_clip_region (b, area_region);
1779 r.bordergc = a;
1780 cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r);
1782 r.bordergc = b;
1783 cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r);
1785 gdk_gc_set_clip_region (a, NULL);
1786 gdk_gc_set_clip_region (b, NULL);
1788 else if (shadow_type == GTK_SHADOW_IN || shadow_type == GTK_SHADOW_OUT)
1790 r.topleft = (shadow_type == GTK_SHADOW_OUT) ? style->light_gc[state_type] : clearlooks_style->shade_gc[1];
1791 r.bottomright = (shadow_type == GTK_SHADOW_OUT) ? clearlooks_style->shade_gc[1] : style->light_gc[state_type];
1792 r.bordergc = clearlooks_style->shade_gc[5];
1794 gdk_gc_set_clip_region (r.bordergc, area_region);
1795 gdk_gc_set_clip_region (r.topleft, area_region);
1796 gdk_gc_set_clip_region (r.bottomright, area_region);
1798 cl_draw_rectangle (window, widget, style, x, y, width, height, &r);
1800 cl_draw_shadow (window, widget, style, x, y, width, height, &r);
1802 gdk_gc_set_clip_region (r.bordergc, NULL);
1803 gdk_gc_set_clip_region (r.topleft, NULL);
1804 gdk_gc_set_clip_region (r.bottomright, NULL);
1807 if (area_region)
1808 gdk_region_destroy (area_region);
1811 /**************************************************************************/
1812 static void
1813 draw_hline (GtkStyle *style,
1814 GdkWindow *window,
1815 GtkStateType state_type,
1816 GdkRectangle *area,
1817 GtkWidget *widget,
1818 const gchar *detail,
1819 gint x1,
1820 gint x2,
1821 gint y)
1823 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1825 #if DEBUG
1826 printf("draw_hline\n");
1827 #endif
1829 g_return_if_fail (GTK_IS_STYLE (style));
1830 g_return_if_fail (window != NULL);
1832 if (area)
1833 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area);
1835 if (detail && !strcmp (detail, "label"))
1837 if (state_type == GTK_STATE_INSENSITIVE)
1838 gdk_draw_line (window, style->light_gc[state_type], x1 + 1, y + 1, x2 + 1, y + 1);
1840 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
1842 else
1844 gdk_draw_line (window, clearlooks_style->shade_gc[2], x1, y, x2, y);
1846 /* if (DETAIL ("menuitem")) */
1847 gdk_draw_line (window, clearlooks_style->shade_gc[0], x1, y+1, x2, y+1);
1850 if (area)
1851 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL);
1854 /**************************************************************************/
1855 static void
1856 draw_vline (GtkStyle *style,
1857 GdkWindow *window,
1858 GtkStateType state_type,
1859 GdkRectangle *area,
1860 GtkWidget *widget,
1861 const gchar *detail,
1862 gint y1,
1863 gint y2,
1864 gint x)
1866 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1867 gint thickness_light;
1868 gint thickness_dark;
1870 #if DEBUG
1871 printf("draw_vline\n");
1872 #endif
1874 g_return_if_fail (GTK_IS_STYLE (style));
1875 g_return_if_fail (window != NULL);
1877 thickness_light = style->xthickness / 2;
1878 thickness_dark = style->xthickness - thickness_light;
1880 if (area)
1881 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area);
1883 gdk_draw_line (window, clearlooks_style->shade_gc[2], x, y1, x, y2 - 1);
1884 gdk_draw_line (window, clearlooks_style->shade_gc[0], x+1, y1, x+1, y2 - 1);
1886 if (area)
1887 gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL);
1890 /**************************************************************************/
1891 static void
1892 draw_focus (GtkStyle *style,
1893 GdkWindow *window,
1894 GtkStateType state_type,
1895 GdkRectangle *area,
1896 GtkWidget *widget,
1897 const gchar *detail,
1898 gint x,
1899 gint y,
1900 gint width,
1901 gint height)
1903 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1904 GdkPoint points[5];
1905 GdkGC *gc;
1906 gboolean free_dash_list = FALSE;
1907 gint line_width = 1;
1908 gchar *dash_list = "\1\1";
1909 gint dash_len;
1911 #if DEBUG
1912 printf("draw_focus: %s %d %d %d %d\n", detail, x, y, width, height);
1913 #endif
1915 gc = clearlooks_style->shade_gc[6];
1917 if (widget)
1919 gtk_widget_style_get (widget,
1920 "focus-line-width", &line_width,
1921 "focus-line-pattern", (gchar *)&dash_list,
1922 NULL);
1924 free_dash_list = TRUE;
1927 sanitize_size (window, &width, &height);
1929 if (area)
1930 gdk_gc_set_clip_rectangle (gc, area);
1932 gdk_gc_set_line_attributes (gc, line_width,
1933 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
1934 GDK_CAP_BUTT, GDK_JOIN_MITER);
1937 if (detail && !strcmp (detail, "add-mode"))
1939 if (free_dash_list)
1940 g_free (dash_list);
1942 dash_list = "\4\4";
1943 free_dash_list = FALSE;
1946 points[0].x = x + line_width / 2;
1947 points[0].y = y + line_width / 2;
1948 points[1].x = x + width - line_width + line_width / 2;
1949 points[1].y = y + line_width / 2;
1950 points[2].x = x + width - line_width + line_width / 2;
1951 points[2].y = y + height - line_width + line_width / 2;
1952 points[3].x = x + line_width / 2;
1953 points[3].y = y + height - line_width + line_width / 2;
1954 points[4] = points[0];
1956 if (!dash_list[0])
1958 gdk_draw_lines (window, gc, points, 5);
1960 else
1962 dash_len = strlen (dash_list);
1964 if (dash_list[0])
1965 gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
1967 gdk_draw_lines (window, gc, points, 3);
1969 points[2].x += 1;
1971 if (dash_list[0])
1973 gint dash_pixels = 0;
1974 gint i;
1976 /* Adjust the dash offset for the bottom and left so we
1977 * match up at the upper left.
1979 for (i = 0; i < dash_len; i++)
1980 dash_pixels += dash_list[i];
1982 if (dash_len % 2 == 1)
1983 dash_pixels *= 2;
1985 gdk_gc_set_dashes (gc,
1986 dash_pixels - (width + height - 2 * line_width) % dash_pixels,
1987 dash_list, dash_len);
1990 gdk_draw_lines (window, gc, points + 2, 3);
1993 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
1995 if (area)
1996 gdk_gc_set_clip_rectangle (gc, NULL);
1998 if (free_dash_list)
1999 g_free (dash_list);
2002 static void
2003 draw_layout(GtkStyle * style,
2004 GdkWindow * window,
2005 GtkStateType state_type,
2006 gboolean use_text,
2007 GdkRectangle * area,
2008 GtkWidget * widget,
2009 const gchar * detail, gint x, gint y, PangoLayout * layout)
2011 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2013 g_return_if_fail(GTK_IS_STYLE (style));
2014 g_return_if_fail(window != NULL);
2016 parent_class->draw_layout(style, window, state_type, use_text,
2017 area, widget, detail, x, y, layout);
2022 /**************************************************************************/
2023 static void
2024 draw_resize_grip (GtkStyle *style,
2025 GdkWindow *window,
2026 GtkStateType state_type,
2027 GdkRectangle *area,
2028 GtkWidget *widget,
2029 const gchar *detail,
2030 GdkWindowEdge edge,
2031 gint x,
2032 gint y,
2033 gint width,
2034 gint height)
2036 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2037 g_return_if_fail (GTK_IS_STYLE (style));
2038 g_return_if_fail (window != NULL);
2040 if (area)
2042 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2043 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2044 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2047 switch (edge)
2049 case GDK_WINDOW_EDGE_NORTH_WEST:
2050 /* make it square */
2051 if (width < height)
2053 height = width;
2055 else if (height < width)
2057 width = height;
2059 break;
2060 case GDK_WINDOW_EDGE_NORTH:
2061 if (width < height)
2063 height = width;
2065 break;
2066 case GDK_WINDOW_EDGE_NORTH_EAST:
2067 /* make it square, aligning to top right */
2068 if (width < height)
2070 height = width;
2072 else if (height < width)
2074 x += (width - height);
2075 width = height;
2077 break;
2078 case GDK_WINDOW_EDGE_WEST:
2079 if (height < width)
2081 width = height;
2083 break;
2084 case GDK_WINDOW_EDGE_EAST:
2085 /* aligning to right */
2086 if (height < width)
2088 x += (width - height);
2089 width = height;
2091 break;
2092 case GDK_WINDOW_EDGE_SOUTH_WEST:
2093 /* make it square, aligning to bottom left */
2094 if (width < height)
2096 y += (height - width);
2097 height = width;
2099 else if (height < width)
2101 width = height;
2103 break;
2104 case GDK_WINDOW_EDGE_SOUTH:
2105 /* align to bottom */
2106 if (width < height)
2108 y += (height - width);
2109 height = width;
2111 break;
2112 case GDK_WINDOW_EDGE_SOUTH_EAST:
2113 /* make it square, aligning to bottom right */
2114 if (width < height)
2116 y += (height - width);
2117 height = width;
2119 else if (height < width)
2121 x += (width - height);
2122 width = height;
2124 break;
2125 default:
2126 g_assert_not_reached ();
2129 /* Clear background */
2130 gtk_style_apply_default_background (style, window, FALSE,
2131 state_type, area,
2132 x, y, width, height);
2134 switch (edge)
2136 case GDK_WINDOW_EDGE_WEST:
2137 case GDK_WINDOW_EDGE_EAST:
2139 gint xi;
2141 xi = x;
2143 while (xi < x + width)
2145 gdk_draw_line (window,
2146 style->light_gc[state_type],
2147 xi, y,
2148 xi, y + height);
2150 xi++;
2151 gdk_draw_line (window,
2152 clearlooks_style->shade_gc[4],
2153 xi, y,
2154 xi, y + height);
2156 xi += 2;
2159 break;
2160 case GDK_WINDOW_EDGE_NORTH:
2161 case GDK_WINDOW_EDGE_SOUTH:
2163 gint yi;
2165 yi = y;
2167 while (yi < y + height)
2169 gdk_draw_line (window,
2170 style->light_gc[state_type],
2171 x, yi,
2172 x + width, yi);
2174 yi++;
2175 gdk_draw_line (window,
2176 clearlooks_style->shade_gc[4],
2177 x, yi,
2178 x + width, yi);
2180 yi+= 2;
2183 break;
2184 case GDK_WINDOW_EDGE_NORTH_WEST:
2186 gint xi, yi;
2188 xi = x + width;
2189 yi = y + height;
2191 while (xi > x + 3)
2193 gdk_draw_line (window,
2194 clearlooks_style->shade_gc[4],
2195 xi, y,
2196 x, yi);
2198 --xi;
2199 --yi;
2201 gdk_draw_line (window,
2202 style->light_gc[state_type],
2203 xi, y,
2204 x, yi);
2206 xi -= 3;
2207 yi -= 3;
2211 break;
2212 case GDK_WINDOW_EDGE_NORTH_EAST:
2214 gint xi, yi;
2216 xi = x;
2217 yi = y + height;
2219 while (xi < (x + width - 3))
2221 gdk_draw_line (window,
2222 style->light_gc[state_type],
2223 xi, y,
2224 x + width, yi);
2226 ++xi;
2227 --yi;
2229 gdk_draw_line (window,
2230 clearlooks_style->shade_gc[4],
2231 xi, y,
2232 x + width, yi);
2234 xi += 3;
2235 yi -= 3;
2238 break;
2239 case GDK_WINDOW_EDGE_SOUTH_WEST:
2241 gint xi, yi;
2243 xi = x + width;
2244 yi = y;
2246 while (xi > x + 3)
2248 gdk_draw_line (window,
2249 clearlooks_style->shade_gc[4],
2250 x, yi,
2251 xi, y + height);
2253 --xi;
2254 ++yi;
2256 gdk_draw_line (window,
2257 style->light_gc[state_type],
2258 x, yi,
2259 xi, y + height);
2261 xi -= 3;
2262 yi += 3;
2266 break;
2268 case GDK_WINDOW_EDGE_SOUTH_EAST:
2270 gint xi, yi;
2272 xi = x;
2273 yi = y;
2275 while (xi < (x + width - 3))
2277 gdk_draw_line (window,
2278 style->light_gc[state_type],
2279 xi, y + height,
2280 x + width, yi);
2282 ++xi;
2283 ++yi;
2285 gdk_draw_line (window,
2286 clearlooks_style->shade_gc[4],
2287 xi, y + height,
2288 x + width, yi);
2290 xi += 3;
2291 yi += 3;
2294 break;
2295 default:
2296 g_assert_not_reached ();
2297 break;
2300 if (area)
2302 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2303 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2304 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2308 /**************************************************************************/
2310 static void
2311 clearlooks_style_init_from_rc (GtkStyle * style,
2312 GtkRcStyle * rc_style)
2314 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2315 GdkColor *spot_color;
2316 double shades[] = {1.065, 0.93, 0.896, 0.85, 0.768, 0.665, 0.4, 0.205};
2317 int i;
2318 double contrast;
2320 parent_class->init_from_rc (style, rc_style);
2322 contrast = CLEARLOOKS_RC_STYLE (rc_style)->contrast;
2324 clearlooks_style->sunkenmenubar = CLEARLOOKS_RC_STYLE (rc_style)->sunkenmenubar;
2325 clearlooks_style->progressbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->progressbarstyle;
2326 clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle;
2327 clearlooks_style->menuitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->menuitemstyle;
2328 clearlooks_style->listviewitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->listviewitemstyle;
2330 /* Lighter to darker */
2331 for (i = 0; i < 8; i++)
2333 shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->shade[i],
2334 (shades[i]-0.7) * contrast + 0.7);
2337 spot_color = clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (rc_style));
2339 clearlooks_style->spot_color = *spot_color;
2340 shade (&clearlooks_style->spot_color, &clearlooks_style->spot1, 1.42);
2341 shade (&clearlooks_style->spot_color, &clearlooks_style->spot2, 1.05);
2342 shade (&clearlooks_style->spot_color, &clearlooks_style->spot3, 0.65);
2344 shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_UPPER], 0.5);
2345 shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_LOWER], 0.62);
2346 shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_UPPER_ACTIVE], 0.5);
2347 shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_LOWER_ACTIVE], 0.55);
2350 static GdkGC *
2351 realize_color (GtkStyle * style,
2352 GdkColor * color)
2354 GdkGCValues gc_values;
2356 gdk_colormap_alloc_color (style->colormap, color, FALSE, TRUE);
2358 gc_values.foreground = *color;
2360 return gtk_gc_get (style->depth, style->colormap, &gc_values, GDK_GC_FOREGROUND);
2363 static void
2364 clearlooks_style_realize (GtkStyle * style)
2366 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2367 int i;
2369 parent_class->realize (style);
2371 for (i = 0; i < 8; i++)
2372 clearlooks_style->shade_gc[i] = realize_color (style, &clearlooks_style->shade[i]);
2374 for (i=0; i < CL_BORDER_COUNT; i++)
2375 clearlooks_style->border_gc[i] = realize_color (style, &clearlooks_style->border[i]);
2377 clearlooks_style->spot1_gc = realize_color (style, &clearlooks_style->spot1);
2378 clearlooks_style->spot2_gc = realize_color (style, &clearlooks_style->spot2);
2379 clearlooks_style->spot3_gc = realize_color (style, &clearlooks_style->spot3);
2381 /* set light inset color */
2382 for (i=0; i<5; i++)
2384 shade (&style->bg[i], &clearlooks_style->inset_dark[i], 0.93);
2385 gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_dark[i]);
2387 shade (&style->bg[i], &clearlooks_style->inset_light[i], 1.055);
2388 gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_light[i]);
2390 shade (&style->bg[i], &clearlooks_style->listview_bg[i], 1.015);
2391 gdk_rgb_find_color (style->colormap, &clearlooks_style->listview_bg[i]);
2393 /* CREATE GRADIENT FOR BUTTONS */
2394 shade (&style->bg[i], &clearlooks_style->button_g1[i], 1.055);
2395 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g1[i]);
2397 shade (&style->bg[i], &clearlooks_style->button_g2[i], 1.005);
2398 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g2[i]);
2400 shade (&style->bg[i], &clearlooks_style->button_g3[i], 0.98);
2401 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g3[i]);
2403 shade (&style->bg[i], &clearlooks_style->button_g4[i], 0.91);
2404 gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g4[i]);
2409 static void
2410 clearlooks_style_unrealize (GtkStyle * style)
2412 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
2413 int i;
2415 /* We don't free the colors, because we don't know if
2416 * gtk_gc_release() actually freed the GC. FIXME - need
2417 * a way of ref'ing colors explicitely so GtkGC can
2418 * handle things properly.
2420 for (i=0; i < 8; i++)
2421 gtk_gc_release (clearlooks_style->shade_gc[i]);
2423 gtk_gc_release (clearlooks_style->spot1_gc);
2424 gtk_gc_release (clearlooks_style->spot2_gc);
2425 gtk_gc_release (clearlooks_style->spot3_gc);
2427 for (i = 0; i < 5; i++)
2429 if (clearlooks_style->radio_pixmap_nonactive[i] != NULL)
2431 g_object_unref (clearlooks_style->radio_pixmap_nonactive[i]);
2432 clearlooks_style->radio_pixmap_nonactive[i] = NULL;
2433 g_object_unref (clearlooks_style->radio_pixmap_active[i]);
2434 clearlooks_style->radio_pixmap_active[i] = NULL;
2435 g_object_unref (clearlooks_style->radio_pixmap_inconsistent[i]);
2436 clearlooks_style->radio_pixmap_inconsistent[i] = NULL;
2439 if (clearlooks_style->check_pixmap_nonactive[i] != NULL)
2441 g_object_unref (clearlooks_style->check_pixmap_nonactive[i]);
2442 clearlooks_style->check_pixmap_nonactive[i] = NULL;
2443 g_object_unref (clearlooks_style->check_pixmap_active[i]);
2444 clearlooks_style->check_pixmap_active[i] = NULL;
2445 g_object_unref (clearlooks_style->check_pixmap_inconsistent[i]);
2446 clearlooks_style->check_pixmap_inconsistent[i] = NULL;
2450 if (clearlooks_style->radio_pixmap_mask != NULL)
2451 g_object_unref (clearlooks_style->radio_pixmap_mask);
2453 clearlooks_style->radio_pixmap_mask = NULL;
2455 while (progressbars = g_list_first (progressbars))
2456 cl_progressbar_remove (progressbars->data);
2458 if (timer_id != 0)
2460 g_source_remove(timer_id);
2461 timer_id = 0;
2464 parent_class->unrealize (style);
2467 static GdkPixbuf *
2468 set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
2470 GdkPixbuf *target;
2471 guchar *data, *current;
2472 guint x, y, rowstride, height, width;
2474 g_return_val_if_fail (pixbuf != NULL, NULL);
2475 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
2477 /* Returns a copy of pixbuf with it's non-completely-transparent pixels to
2478 have an alpha level "alpha_percent" of their original value. */
2480 target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
2482 if (alpha_percent == 1.0)
2483 return target;
2484 width = gdk_pixbuf_get_width (target);
2485 height = gdk_pixbuf_get_height (target);
2486 rowstride = gdk_pixbuf_get_rowstride (target);
2487 data = gdk_pixbuf_get_pixels (target);
2489 for (y = 0; y < height; y++) {
2490 for (x = 0; x < width; x++) {
2491 /* The "4" is the number of chars per pixel, in this case, RGBA,
2492 the 3 means "skip to the alpha" */
2493 current = data + (y * rowstride) + (x * 4) + 3;
2494 *(current) = (guchar) (*(current) * alpha_percent);
2498 return target;
2501 static GdkPixbuf*
2502 scale_or_ref (GdkPixbuf *src,
2503 int width,
2504 int height)
2506 if (width == gdk_pixbuf_get_width (src) &&
2507 height == gdk_pixbuf_get_height (src)) {
2508 return g_object_ref (src);
2509 } else {
2510 return gdk_pixbuf_scale_simple (src,
2511 width, height,
2512 GDK_INTERP_BILINEAR);
2516 static GdkPixbuf *
2517 render_icon (GtkStyle *style,
2518 const GtkIconSource *source,
2519 GtkTextDirection direction,
2520 GtkStateType state,
2521 GtkIconSize size,
2522 GtkWidget *widget,
2523 const char *detail)
2525 int width = 1;
2526 int height = 1;
2527 GdkPixbuf *scaled;
2528 GdkPixbuf *stated;
2529 GdkPixbuf *base_pixbuf;
2530 GdkScreen *screen;
2531 GtkSettings *settings;
2533 /* Oddly, style can be NULL in this function, because
2534 * GtkIconSet can be used without a style and if so
2535 * it uses this function.
2538 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2540 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2542 if (widget && gtk_widget_has_screen (widget)) {
2543 screen = gtk_widget_get_screen (widget);
2544 settings = gtk_settings_get_for_screen (screen);
2545 } else if (style->colormap) {
2546 screen = gdk_colormap_get_screen (style->colormap);
2547 settings = gtk_settings_get_for_screen (screen);
2548 } else {
2549 settings = gtk_settings_get_default ();
2550 GTK_NOTE (MULTIHEAD,
2551 g_warning ("Using the default screen for gtk_default_render_icon()"));
2555 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) {
2556 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2557 return NULL;
2560 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2561 * leave it alone.
2563 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2564 scaled = scale_or_ref (base_pixbuf, width, height);
2565 else
2566 scaled = g_object_ref (base_pixbuf);
2568 /* If the state was wildcarded, then generate a state. */
2569 if (gtk_icon_source_get_state_wildcarded (source)) {
2570 if (state == GTK_STATE_INSENSITIVE) {
2571 stated = set_transparency (scaled, 0.3);
2572 #if 0
2573 stated =
2574 gdk_pixbuf_composite_color_simple (scaled,
2575 gdk_pixbuf_get_width (scaled),
2576 gdk_pixbuf_get_height (scaled),
2577 GDK_INTERP_BILINEAR, 128,
2578 gdk_pixbuf_get_width (scaled),
2579 style->bg[state].pixel,
2580 style->bg[state].pixel);
2581 #endif
2582 gdk_pixbuf_saturate_and_pixelate (stated, stated,
2583 0.1, FALSE);
2585 g_object_unref (scaled);
2586 } else if (state == GTK_STATE_PRELIGHT) {
2587 stated = gdk_pixbuf_copy (scaled);
2589 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2590 1.2, FALSE);
2592 g_object_unref (scaled);
2593 } else {
2594 stated = scaled;
2597 else
2598 stated = scaled;
2600 return stated;
2603 static void
2604 clearlooks_style_init (ClearlooksStyle * style)
2608 static void
2609 clearlooks_style_class_init (ClearlooksStyleClass * klass)
2611 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
2613 parent_class = g_type_class_peek_parent (klass);
2615 style_class->realize = clearlooks_style_realize;
2616 style_class->unrealize = clearlooks_style_unrealize;
2617 style_class->init_from_rc = clearlooks_style_init_from_rc;
2618 style_class->draw_focus = draw_focus;
2619 style_class->draw_resize_grip = draw_resize_grip;
2620 style_class->draw_handle = draw_handle;
2621 style_class->draw_vline = draw_vline;
2622 style_class->draw_hline = draw_hline;
2623 style_class->draw_slider = draw_slider;
2624 style_class->draw_shadow_gap = draw_shadow_gap;
2625 style_class->draw_arrow = clearlooks_draw_arrow;
2626 style_class->draw_check = draw_check;
2627 style_class->draw_tab = draw_tab;
2628 style_class->draw_box = draw_box;
2629 style_class->draw_shadow = draw_shadow;
2630 style_class->draw_box_gap = draw_box_gap;
2631 style_class->draw_extension = draw_extension;
2632 style_class->draw_option = draw_option;
2633 style_class->draw_layout = draw_layout;
2634 style_class->render_icon = render_icon;
2635 style_class->draw_flat_box = draw_flat_box;
2638 GType clearlooks_type_style = 0;
2640 void
2641 clearlooks_style_register_type (GTypeModule * module)
2643 static const GTypeInfo object_info =
2645 sizeof (ClearlooksStyleClass),
2646 (GBaseInitFunc) NULL,
2647 (GBaseFinalizeFunc) NULL,
2648 (GClassInitFunc) clearlooks_style_class_init,
2649 NULL, /* class_finalize */
2650 NULL, /* class_data */
2651 sizeof (ClearlooksStyle),
2652 0, /* n_preallocs */
2653 (GInstanceInitFunc) clearlooks_style_init,
2654 NULL
2657 clearlooks_type_style = g_type_module_register_type (module,
2658 GTK_TYPE_STYLE,
2659 "ClearlooksStyle",
2660 &object_info, 0);