From bc89fe0147c04b67141936d109c00dfd4d69cc4b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 12 Dec 2008 14:43:24 +0000 Subject: most of the 2.X->3.0 commit (up to rev 4299) except for gtk2_ardour/editor_canvas.cc; builds and runs and does a few specific things but expect it to be buggy for a while yet git-svn-id: svn://localhost/ardour2/branches/3.0@4313 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/clearlooks-older/SConscript | 36 + libs/clearlooks-older/bits.c | 121 ++ libs/clearlooks-older/clearlooks_draw.c | 1293 ++++++++++++ libs/clearlooks-older/clearlooks_draw.h | 159 ++ libs/clearlooks-older/clearlooks_rc_style.c | 392 ++++ libs/clearlooks-older/clearlooks_rc_style.h | 57 + libs/clearlooks-older/clearlooks_style.c | 2661 +++++++++++++++++++++++++ libs/clearlooks-older/clearlooks_style.h | 108 + libs/clearlooks-older/clearlooks_theme_main.c | 37 + libs/clearlooks-older/cpdll.sh | 2 + libs/clearlooks-older/support.c | 981 +++++++++ libs/clearlooks-older/support.h | 110 + 12 files changed, 5957 insertions(+) create mode 100644 libs/clearlooks-older/SConscript create mode 100644 libs/clearlooks-older/bits.c create mode 100644 libs/clearlooks-older/clearlooks_draw.c create mode 100644 libs/clearlooks-older/clearlooks_draw.h create mode 100644 libs/clearlooks-older/clearlooks_rc_style.c create mode 100644 libs/clearlooks-older/clearlooks_rc_style.h create mode 100644 libs/clearlooks-older/clearlooks_style.c create mode 100644 libs/clearlooks-older/clearlooks_style.h create mode 100644 libs/clearlooks-older/clearlooks_theme_main.c create mode 100755 libs/clearlooks-older/cpdll.sh create mode 100644 libs/clearlooks-older/support.c create mode 100644 libs/clearlooks-older/support.h (limited to 'libs/clearlooks-older') diff --git a/libs/clearlooks-older/SConscript b/libs/clearlooks-older/SConscript new file mode 100644 index 0000000000..4feff6db90 --- /dev/null +++ b/libs/clearlooks-older/SConscript @@ -0,0 +1,36 @@ +# -*- python -*- + +import os.path +import glob + +libclearlooks_files = [ + 'clearlooks_draw.c', + 'clearlooks_rc_style.c', + 'clearlooks_style.c', + 'clearlooks_theme_main.c', + 'support.c' ] + +Import ('env install_prefix') + +clearlooks = env.Clone() + +clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0` ', + LINKFLAGS = ' `pkg-config --libs gtk+-2.0` ') + +if env['GTKOSX']: + clearlooks.Append (CCFLAGS = '-DGTKOSX') + +libclearlooks = clearlooks.SharedLibrary('clearlooks', libclearlooks_files) + +usable_libclearlooks = clearlooks.Install ('engines', libclearlooks) +Default (usable_libclearlooks) + +env.Alias('install', + env.Install(os.path.join(install_prefix,env['LIBDIR'], 'ardour2', 'engines'), + libclearlooks)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'bits.c'] + + libclearlooks_files + + glob.glob('*.h') + )) diff --git a/libs/clearlooks-older/bits.c b/libs/clearlooks-older/bits.c new file mode 100644 index 0000000000..1e871bc5d3 --- /dev/null +++ b/libs/clearlooks-older/bits.c @@ -0,0 +1,121 @@ +static unsigned char dot_intensity[] = { +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x98,0xb9,0xc6,0xb9,0x91,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0xbd,0xac,0x9e,0x65,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xc6,0xac,0x9e,0x96,0x5c,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0x9e,0x96,0x62,0x55,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x91,0x65,0x5c,0x55,0x68,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +}; +static unsigned char dot_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static unsigned char circle_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x23,0x62,0x92,0xb3,0xb2,0x95,0x2b,0x00,0x00,0x00, +0x00,0x00,0x3e,0xab,0xc9,0xeb,0xf9,0xf5,0xfd,0xff,0x57,0x00,0x00, +0x00,0x1f,0xb5,0xd8,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x67,0xb9,0xf2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x9a,0xe2,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0xba,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xc0,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x2b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x00,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,0x00, +0x00,0x00,0x00,0x2b,0x9c,0xe5,0xff,0xe5,0x9c,0x2b,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char outline_alpha[] = { +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +}; +static unsigned char inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_base_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, 137, 151,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, 183, 172, 7,0x00,0x00, +0x00,0x00, 12, 18,0x00,0x00, 3, 161, 233, 27,0x00,0x00,0x00, +0x00,0x00, 199, 239, 101,0x00, 85, 253, 108,0x00,0x00,0x00,0x00, +0x00,0x00, 83, 245, 250, 75, 206, 230, 8,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 104, 252, 243, 253, 124,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 2, 162, 255, 241, 28,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, 18, 228, 163,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00, 78, 62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/libs/clearlooks-older/clearlooks_draw.c b/libs/clearlooks-older/clearlooks_draw.c new file mode 100644 index 0000000000..144be35152 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_draw.c @@ -0,0 +1,1293 @@ +#include "clearlooks_draw.h" +#include "clearlooks_style.h" + +#include "support.h" + +/** WANTED: + FASTER GRADIENT FILL FUNCTION, POSSIBLY USING XRENDER. **/ + +static void cl_draw_borders (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +static void cl_draw_line (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x1, int y1, int x2, int y2, CLBorderType border, + CLRectangle *r); + +static void cl_draw_corner (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, + CLRectangle *r, CLCornerSide corner); + +static void cl_draw_fill (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_draw_rectangle (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + if (r->fillgc) + { + cl_draw_fill(window, widget, style, x, y, width, height, r); + } + + if (r->bordergc) + { + cl_draw_borders(window, widget, style, x, y, width, height, r); + } +} + + +static void cl_get_coords ( CLBorderType border, + int x, int y, int width, int height, + CLRectangle *r, int *x1, int *y1, int *x2, int *y2) +{ + switch (border) + { + case CL_BORDER_TOP: + *x1 = x + r->corners[CL_CORNER_TOPLEFT]; + *x2 = *x1 + width - r->corners[CL_CORNER_TOPLEFT] - r->corners[CL_CORNER_TOPRIGHT] - 1; + *y1 = *y2 = y; + break; + case CL_BORDER_BOTTOM: + *x1 = x + r->corners[CL_CORNER_BOTTOMLEFT]; + *x2 = *x1 + width - r->corners[CL_CORNER_BOTTOMLEFT] - r->corners[CL_CORNER_BOTTOMRIGHT] - 1; + *y1 = *y2 = y + height - 1; + break; + case CL_BORDER_LEFT: + *x1 = *x2 = x; + *y1 = y + r->corners[CL_CORNER_TOPLEFT]; + *y2 = *y1 + height - r->corners[CL_CORNER_TOPLEFT] - r->corners[CL_CORNER_BOTTOMLEFT] - 1; + break; + case CL_BORDER_RIGHT: + *x1 = *x2 = x + width - 1; + *y1 = y + r->corners[CL_CORNER_TOPRIGHT]; + *y2 = *y1 + height - r->corners[CL_CORNER_TOPRIGHT] - r->corners[CL_CORNER_BOTTOMRIGHT] - 1; + break; + } +} + +void cl_draw_borders (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + int x1, y1, x2, y2, i; + + if (r->bordergc == NULL) + return; + + for ( i=0; i<4; i++) /* draw all four borders + corners */ + { + cl_get_coords (i, x, y, width, height, r, &x1, &y1, &x2, &y2); + cl_draw_line (window, widget, style, x1, y1, x2, y2, i, r); + cl_draw_corner (window, widget, style, x, y, width, height, r, i ); + } +} + + +static GdkColor cl_gc_get_foreground(GdkGC *gc) +{ + GdkGCValues values; + gdk_gc_get_values (gc, &values); + return values.foreground; +} + +static void cl_draw_line (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x1, int y1, int x2, int y2, CLBorderType border, + CLRectangle *r) +{ + if (r->gradient_type == CL_GRADIENT_NONE || + r->border_gradient.from == NULL || r->border_gradient.to == NULL ) + { + gdk_draw_line (window, r->bordergc, x1, y1, x2, y2); + } + else if (r->gradient_type == CL_GRADIENT_HORIZONTAL && (border == CL_BORDER_TOP || border == CL_BORDER_BOTTOM)) + { + draw_vgradient (window, r->bordergc, style, + x1, y1, x2-x1+1, 1, + r->border_gradient.from, r->border_gradient.to); + } + else if (r->gradient_type == CL_GRADIENT_VERTICAL && (border == CL_BORDER_LEFT || border == CL_BORDER_RIGHT)) + { + draw_hgradient (window, r->bordergc, style, + x1, y1, 1, y2-y1+1, + r->border_gradient.from, r->border_gradient.to); + } + else + { + GdkColor tmp_color = cl_gc_get_foreground (r->bordergc); + + if (r->gradient_type == CL_GRADIENT_HORIZONTAL && border == CL_BORDER_LEFT || + r->gradient_type == CL_GRADIENT_VERTICAL && border == CL_BORDER_TOP) + gdk_gc_set_foreground (r->bordergc, r->border_gradient.from); + else + gdk_gc_set_foreground (r->bordergc, r->border_gradient.to); + + gdk_draw_line (window, r->bordergc, x1, y1, x2, y2); + + gdk_gc_set_foreground (r->bordergc, &tmp_color); + } +} + +static GdkColor *cl_get_gradient_corner_color (CLRectangle *r, CLCornerSide corner) +{ + GdkColor *color; + + if (r->border_gradient.from == NULL || r->border_gradient.to == NULL) + { + color = NULL; + } + else if ((r->gradient_type == CL_GRADIENT_HORIZONTAL && (corner == CL_CORNER_TOPLEFT || corner == CL_CORNER_BOTTOMLEFT)) || + (r->gradient_type == CL_GRADIENT_VERTICAL && (corner == CL_CORNER_TOPLEFT || corner == CL_CORNER_TOPRIGHT))) + { + color = r->border_gradient.from; + } + else /* no gradient or other corner */ + { + color = r->border_gradient.to; + } + + return color; +} + +static void cl_draw_corner (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, + CLRectangle *r, CLCornerSide corner) +{ + GdkColor *color; + GdkColor aacolor; /* anti-aliasing color */ + GdkGCValues values; + GdkColor tmp; + GdkColor *bgcolor; + + int x1; + int y1; + + if (r->corners[corner] == CL_CORNER_NONE) + return; + + color = cl_get_gradient_corner_color (r, corner); + gdk_gc_get_values (r->bordergc, &values); + + if (color == NULL) + { + tmp = values.foreground; + gdk_colormap_query_color (gtk_widget_get_colormap(widget), values.foreground.pixel, &tmp); + color = &tmp; + } + + bgcolor = get_parent_bgcolor(widget); + + if (bgcolor == NULL) + { + bgcolor = color; + } + + blend (style->colormap, bgcolor, color, &aacolor, 70); + + if (r->corners[corner] == CL_CORNER_ROUND) + { + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x+1 : x+width - 2; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y+1 : y+height - 2; + + gdk_gc_set_foreground (r->bordergc, color); + gdk_draw_point (window, r->bordergc, x1, y1); + + gdk_gc_set_foreground (r->bordergc, &aacolor); + + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x+1 : x+width-2; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y : y+height-1; + + gdk_draw_point (window, r->bordergc, x1, y1); + + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x : x+width-1; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y+1 : y+height-2; + + gdk_draw_point (window, r->bordergc, x1, y1); + + } + else if (r->corners[corner] == CL_CORNER_NARROW) + { + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x : x+width-1; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y : y+height-1; + + gdk_gc_set_foreground (r->bordergc, &aacolor); + gdk_draw_point (window, r->bordergc, x1, y1); + } + + gdk_gc_set_foreground (r->bordergc, &values.foreground); +} + +static void cl_draw_fill (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + if (r->gradient_type == CL_GRADIENT_NONE || + r->fill_gradient.from == NULL || r->fill_gradient.to == NULL) + { + gdk_draw_rectangle (window, r->fillgc, TRUE, + x+1, y+1, width-2, height-2); + } + else if (r->gradient_type == CL_GRADIENT_HORIZONTAL) + { + draw_vgradient (window, r->fillgc, gtk_widget_get_style(widget), + x+1, y+1, width-2, height-2, + r->fill_gradient.from, r->fill_gradient.to); + } + else if (r->gradient_type == CL_GRADIENT_VERTICAL) + { + draw_hgradient (window, r->fillgc, gtk_widget_get_style(widget), + x+1, y+1, width-2, height-2, + r->fill_gradient.from, r->fill_gradient.to); + } +} + +void cl_rectangle_set_button(CLRectangle *r, GtkStyle *style, + GtkStateType state_type, gboolean has_default, + gboolean has_focus, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + GdkGC *border_gc = clearlooks_style->border_gc[CL_BORDER_UPPER+my_state_type]; + + + cl_rectangle_init (r, style->bg_gc[state_type], + clearlooks_style->border_gc[CL_BORDER_UPPER+my_state_type], + tl, tr, bl, br); + + if (state_type != GTK_STATE_INSENSITIVE && !has_default) + { + cl_rectangle_set_gradient (&r->border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + } + else if (has_default) + r->bordergc = style->black_gc; + else + r->bordergc = clearlooks_style->shade_gc[4]; + + r->gradient_type = CL_GRADIENT_VERTICAL; + + r->topleft = (state_type != GTK_STATE_ACTIVE) ? style->light_gc[state_type] : clearlooks_style->shade_gc[4]; + r->bottomright = (state_type != GTK_STATE_ACTIVE) ? clearlooks_style->shade_gc[1] : NULL; + + shade (&style->bg[state_type], &r->tmp_color, 0.93); + + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->bg[state_type], + &r->tmp_color); +} + +void cl_rectangle_set_entry (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br, + gboolean has_focus) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *bordergc; + + if (has_focus) + bordergc = clearlooks_style->spot3_gc; + else if (state_type != GTK_STATE_INSENSITIVE) + bordergc = clearlooks_style->border_gc[CL_BORDER_LOWER]; + else + bordergc = clearlooks_style->shade_gc[3]; + + cl_rectangle_init (r, style->base_gc[state_type], bordergc, + tl, tr, bl, br); + + if (state_type != GTK_STATE_INSENSITIVE ) + r->topleft = (has_focus) ? clearlooks_style->spot1_gc + : style->bg_gc[GTK_STATE_NORMAL]; + + if (has_focus) + r->bottomright = clearlooks_style->spot1_gc; + else if (state_type == GTK_STATE_INSENSITIVE) + r->bottomright = style->base_gc[state_type]; +} + +void cl_draw_shadow(GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int x1, y1, x2, y2; + + if (r->bottomright != NULL) + { + x1 = x+1+(r->corners[CL_CORNER_BOTTOMLEFT]/2); + y1 = y2 = y+height-2; + x2 = x+width - 1 - (1+r->corners[CL_CORNER_BOTTOMRIGHT]/2); + + gdk_draw_line (window, r->bottomright, x1, y1, x2, y2); + + x1 = x2 = x+width-2; + y1 = y+1+(r->corners[CL_CORNER_TOPRIGHT]/2); + y2 = y+height - 1 - (1+r->corners[CL_CORNER_BOTTOMRIGHT]/2); + + gdk_draw_line (window, r->bottomright, x1, y1, x2, y2); + } + + if (r->topleft != NULL) + { + x1 = x+1+(r->corners[CL_CORNER_TOPLEFT]/2); + y1 = y2 = y+1; + x2 = x+width-1-(1+r->corners[CL_CORNER_TOPRIGHT]/2); + + gdk_draw_line (window, r->topleft, x1, y1, x2, y2); + + x1 = x2 = x+1; + y1 = y+1+(r->corners[CL_CORNER_TOPLEFT]/2); + y2 = y+height-1-(1+r->corners[CL_CORNER_BOTTOMLEFT]/2); + + gdk_draw_line (window, r->topleft, x1, y1, x2, y2); + } +} + +void cl_rectangle_set_color (CLGradient *g, GdkColor *color) +{ + g->from = color; + g->to = color; +} + +void cl_rectangle_set_gradient (CLGradient *g, GdkColor *from, GdkColor *to) +{ + g->from = from; + g->to = to; +} + +void cl_rectangle_init (CLRectangle *r, + GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br) +{ + r->gradient_type = CL_GRADIENT_NONE; + + r->border_gradient.from = r->border_gradient.to = NULL; + r->fill_gradient.from = r->fill_gradient.to = NULL; + + r->fillgc = fillgc; + r->bordergc = bordergc; + + r->topleft = NULL; + r->bottomright = NULL; + + r->corners[CL_CORNER_TOPLEFT] = tl; + r->corners[CL_CORNER_TOPRIGHT] = tr; + r->corners[CL_CORNER_BOTTOMLEFT] = bl; + r->corners[CL_CORNER_BOTTOMRIGHT] = br; +} + +void cl_rectangle_set_corners (CLRectangle *r, int tl, int tr, int bl, int br) +{ + r->corners[CL_CORNER_TOPLEFT] = tl; + r->corners[CL_CORNER_TOPRIGHT] = tr; + r->corners[CL_CORNER_BOTTOMLEFT] = bl; + r->corners[CL_CORNER_BOTTOMRIGHT] = br; +} + +void cl_set_corner_sharpness (const gchar *detail, GtkWidget *widget, CLRectangle *r) +{ + if (widget->parent && GTK_IS_COMBO_BOX_ENTRY (widget->parent) || GTK_IS_COMBO (widget->parent)) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int cl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int cr = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, cl, cr, cl, cr); + } + else if (detail && !strcmp (detail, "spinbutton_up")) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int tl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int tr = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, tl, tr, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else if (detail && !strcmp (detail, "spinbutton_down")) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int bl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int br = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, CL_CORNER_NONE, CL_CORNER_NONE, + bl, br); + } + else + { + cl_rectangle_set_corners (r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + }; +} + +void cl_rectangle_set_clip_rectangle (CLRectangle *r, GdkRectangle *area) +{ + if (area == NULL) + return; + + if (r->fillgc) + gdk_gc_set_clip_rectangle (r->fillgc, area); + + if (r->bordergc) + gdk_gc_set_clip_rectangle (r->bordergc, area); + + if (r->topleft) + gdk_gc_set_clip_rectangle (r->topleft, area); + + if (r->bottomright) + gdk_gc_set_clip_rectangle (r->bottomright, area); +} + +void cl_rectangle_reset_clip_rectangle (CLRectangle *r) +{ + if (r->fillgc) + gdk_gc_set_clip_rectangle (r->fillgc, NULL); + + if (r->bordergc) + gdk_gc_set_clip_rectangle (r->bordergc, NULL); + + if (r->topleft) + gdk_gc_set_clip_rectangle (r->topleft, NULL); + + if (r->bottomright) + gdk_gc_set_clip_rectangle (r->bottomright, NULL); +} + +void cl_rectangle_reset (CLRectangle *r, GtkStyle *style) +{ + cl_rectangle_init (r, + NULL, NULL, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); +} + +static void cl_progressbar_points_transform (GdkPoint *points, int npoints, + int offset, gboolean is_horizontal) +{ + int i; + for ( i=0; iwindow, width, height, -1); + + GdkColor tmp_color; + shade (&clearlooks_style->spot2, &tmp_color, 0.90); + + if (is_horizontal) + draw_hgradient (tmp, style->black_gc, style, 0, 0, width, height, + &clearlooks_style->spot2, &tmp_color ); + else + draw_vgradient (tmp, style->black_gc, style, 0, 0, width, height, + &tmp_color, &clearlooks_style->spot2); /* TODO: swap for RTL */ + + if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT || + orientation == GTK_PROGRESS_BOTTOM_TO_TOP) + { + offset = -offset; + xdir = -1; + } + + if (get_direction (widget) == GTK_TEXT_DIR_RTL) + offset = -offset; + + if (is_horizontal) + { + points[0] = (GdkPoint){xdir*(topright - stripe_width - topright_div_2), 0}; /* topleft */ + points[1] = (GdkPoint){xdir*(topright - topright_div_2), 0}; /* topright */ + points[2] = (GdkPoint){xdir*(stripe_width - topright_div_2), height}; /* bottomright */ + points[3] = (GdkPoint){xdir*(-topright_div_2), height}; /* bottomleft */ + } + else + { + points[0] = (GdkPoint){height, xdir*(topright - stripe_width - topright_div_2)}; /* topleft */ + points[1] = (GdkPoint){height, xdir*(topright - topright_div_2)}; /* topright */ + points[2] = (GdkPoint){0, xdir*(stripe_width - topright_div_2)}; /* bottomright */ + points[3] = (GdkPoint){0, xdir*(-topright_div_2)}; /* bottomleft */ + } + + + shift = (stripe_width*2)/(double)10; + cl_progressbar_points_transform (points, 4, (offset*shift), is_horizontal); + + trans = (width/2)-1-(stripe_width*2); + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + cl_progressbar_points_transform (points, 4, -trans, is_horizontal); + + trans = width/2-1; + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + cl_progressbar_points_transform (points, 4, -trans, is_horizontal); + + trans = (width/2)-1+(stripe_width*2); + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + + return tmp; +} + +/* could be improved, I think. */ +void cl_progressbar_fill (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, GdkGC *gc, + gint x, gint y, + gint width, gint height, + guint8 offset, GdkRectangle *area) +{ + GtkProgressBarOrientation orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget)); + gint size = (orientation == GTK_PROGRESS_LEFT_TO_RIGHT || orientation == GTK_PROGRESS_RIGHT_TO_LEFT) ? height : width; + GdkPixmap *tile = cl_progressbar_tile_new (widget->window, widget, style, size, offset); + + gint nx = x, + ny = y, + nwidth = height, + nheight = width; + + gdk_gc_set_clip_rectangle (gc, area); + + switch (orientation) + { + case GTK_PROGRESS_LEFT_TO_RIGHT: + { + while (nx <= x + width ) + { + if (nx + nwidth > x+width ) nwidth = (x+width) - nx; + gdk_draw_drawable (drawable, gc, tile, 0, 0, nx, y, nwidth, height); + if (height <= 1) + nx += 1; + else + nx += (height-1 + !(height % 2)); + } + break; + } + case GTK_PROGRESS_RIGHT_TO_LEFT: + { + gint src_x = 0, dst_x; + nx += width; + while (nx >= x ) + { + dst_x = nx - height; + if (dst_x < x ) + { + src_x = x - dst_x; + dst_x = x; + } + gdk_draw_drawable (drawable, gc, tile, src_x, 0, dst_x, y, nwidth, height); + if (height <= 1) + nx -= 1; + else + nx -= (height-1 + !(height % 2)); + } + break; + } + case GTK_PROGRESS_TOP_TO_BOTTOM: + { + while (ny <= y + height ) + { + if (ny + nheight > y+height ) nheight = (y+height) - ny; + gdk_draw_drawable (drawable, gc, tile, 0, 0, x, ny, width, nheight); + if (width <= 1) + ny += 1; + else + ny += (width-1 + !(width % 2)); + } + break; + } + case GTK_PROGRESS_BOTTOM_TO_TOP: + { + gint src_y = 0, dst_y; + ny += height; + while (ny >= y ) + { + dst_y = ny - width; + if (dst_y < y ) + { + src_y = y - dst_y; + dst_y = y; + } + gdk_draw_drawable (drawable, gc, tile, 0, src_y, x, dst_y, width, width); + if (width <= 1) + ny -= 1; + else + ny -= (width-1 + !(width % 2)); + } + break; + } + } + + gdk_gc_set_clip_rectangle (gc, NULL); + + g_object_unref (tile); +} + +GdkColor cl_gc_set_fg_color_shade (GdkGC *gc, GdkColormap *colormap, + GdkColor *from, gfloat s) +{ + GdkColor tmp_color; + GdkGCValues values; + + shade (from, &tmp_color, s); + gdk_gc_get_values (gc, &values); + gdk_rgb_find_color (colormap, &tmp_color); + gdk_gc_set_foreground (gc, &tmp_color); + + return values.foreground; +} + +/* #warning MOVE THIS TO SUPPORT.C/H SO THE DRAW_CORNER FUNCTION CAN USE IT. OR, MAKE DRAW_CORNER USE IT SOME OTHER WAY. */ + +static void cl_get_window_style_state (GtkWidget *widget, GtkStyle **style, GtkStateType *state_type) +{ + GtkStyle *windowstyle = NULL; + GtkWidget *tmpwidget = widget; + GtkStateType windowstate; + + if (widget && GTK_IS_ENTRY (widget)) + tmpwidget = tmpwidget->parent; + + while (tmpwidget && GTK_WIDGET_NO_WINDOW (tmpwidget) && !GTK_IS_NOTEBOOK(tmpwidget)) + { + tmpwidget = tmpwidget->parent; + } + + *style = tmpwidget->style; + *state_type = GTK_WIDGET_STATE(tmpwidget); +} + +static GdkGC *cl_get_window_bg_gc (GtkWidget *widget) +{ + GtkStyle *style; + GtkStateType state_type; + + cl_get_window_style_state (widget, &style, &state_type); + + return style->bg_gc[state_type]; +} + +/****************************************************************************** + * DRAW THE MIGHTY WIDGETS! * + ******************************************************************************/ + +void cl_draw_inset (GtkStyle *style, GdkWindow *window, GtkWidget *widget, + GdkRectangle *area, + gint x, gint y, gint width, gint height, + int tl, int tr, int bl, int br ) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + ClearlooksStyle *clwindowstyle; /* style of the window this widget is on */ + GtkStateType windowstate; + CLRectangle r; + + cl_rectangle_init (&r, NULL, style->black_gc, + tl, tr, bl, br); + + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_get_window_style_state(widget, (GtkStyle**)&clwindowstyle, &windowstate); + + g_assert (clwindowstyle != NULL); + + if (GTK_WIDGET_HAS_DEFAULT (widget)) + { + r.bordergc = style->mid_gc[GTK_STATE_NORMAL]; + } + else + { + cl_rectangle_set_gradient (&r.border_gradient, + &clwindowstyle->inset_dark[windowstate], + &clwindowstyle->inset_light[windowstate]); + } + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw a normal (toggle)button. Not spinbuttons.*/ +void cl_draw_button(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + GdkGC *bg_gc = NULL; + gboolean is_active = FALSE; + CLRectangle r; + + /* Get the background color of the window we're on */ + bg_gc = cl_get_window_bg_gc(widget); + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + is_active = TRUE; + + if (GTK_IS_TOGGLE_BUTTON(widget) && + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) && + state_type == GTK_STATE_PRELIGHT) + { + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->shade[1], &clearlooks_style->shade[1]); + r.topleft = clearlooks_style->shade_gc[3]; + r.bottomright = clearlooks_style->shade_gc[1]; + + is_active = TRUE; + } + + if (!is_active) + r.fillgc = NULL; + + if (!GTK_IS_NOTEBOOK (widget->parent)) + { + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + } + + /* Draw "sunken" look when border thickness is more than 2 pixels.*/ + if (style->xthickness > 2 && style->ythickness > 2) + { + x++; + y++; + height-=2; + width-=2; + } + + /* Don't draw the normal gradient for normal buttons. */ + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + + if (!is_active) + { + int tmp_height = (float)height*0.25; + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+2,width-4,tmp_height, + &clearlooks_style->button_g1[state_type], + &clearlooks_style->button_g2[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2, y+2+tmp_height, width-4, height-3-tmp_height*2, + &clearlooks_style->button_g2[state_type], + &clearlooks_style->button_g3[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+height-tmp_height-1,width-4,tmp_height, + &clearlooks_style->button_g3[state_type], + &clearlooks_style->button_g4[state_type]); + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw spinbuttons. */ +void cl_draw_spinbutton(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + GdkRectangle new_area; + + int tl = CL_CORNER_NONE, tr = CL_CORNER_NONE, + bl = CL_CORNER_NONE, br = CL_CORNER_NONE; + + if (area == NULL) + { + new_area.x = x; + new_area.y = y; + new_area.width = width; + new_area.height = height; + area = &new_area; + } + + if (!strcmp (detail, "spinbutton")) /* draws the 'back' of the spinbutton */ + { + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + gdk_gc_set_clip_rectangle (bg_gc, area); + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + gdk_gc_set_clip_rectangle (bg_gc, NULL); + + if (style->xthickness > 2 && style->ythickness > 2) + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + return; + } + + if (!strcmp (detail, "spinbutton_up")) + { + tr = CL_CORNER_ROUND; + + (style->xthickness > 2 && style->ythickness > 2) ? y++ : height++; + } + + if (!strcmp (detail, "spinbutton_down")) + { + br = CL_CORNER_ROUND; + + if (style->xthickness > 2 && style->ythickness > 2) + height--; + } + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + tl, tr, + bl, br); + width--; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_combobox_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + gboolean has_focus = GTK_WIDGET_HAS_FOCUS (widget); + + int cl = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND, + cr = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + if (rtl) + { + if (!has_focus) + { + x -= 1; + width +=1; + } + } + else + { + width += 2; + if (has_focus) width--; /* this gives us a 2px focus line at the right side. */ + } + + cl_rectangle_set_entry (&r, style, state_type, + cl, cr, cl, cr, + has_focus); + + gdk_gc_set_clip_rectangle (bg_gc, area); + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + gdk_gc_set_clip_rectangle (bg_gc, NULL); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + cl, cr, cl, cr); + + y++; + x++; + width-=2; + height-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_combobox_button (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + gboolean is_active = FALSE; + gboolean draw_inset = FALSE; + CLRectangle r; + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + is_active = TRUE; + else + r.fillgc = NULL; + + /* Seriously, why can't non-gtk-apps at least try to be decent citizens? + Take this fscking OpenOffice.org 1.9 for example. The morons responsible + for this utter piece of crap give the clip size wrong values! :'( */ + + if (area) + { + area->x = x; + area->y = y; + area->width = width; + area->height = height; + } + + x--; + width++; + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (GTK_IS_COMBO(widget->parent)) + draw_inset = (widget->parent->style->xthickness > 2 && + widget->parent->style->ythickness > 2); + else + draw_inset = (style->xthickness > 2 && style->ythickness > 2); + + if (draw_inset) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + x++; + y++; + height-=2; + width-=2; + } + else + { + x++; + width--; + } + + if (area) + cl_rectangle_set_clip_rectangle (&r, area); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + if (!is_active) + { + int tmp_height = (float)height*0.25; + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+2,width-4,tmp_height, + &clearlooks_style->button_g1[state_type], + &clearlooks_style->button_g2[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2, y+2+tmp_height, width-4, height-3-tmp_height*2, + &clearlooks_style->button_g2[state_type], + &clearlooks_style->button_g3[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+height-tmp_height-1,width-4,tmp_height, + &clearlooks_style->button_g3[state_type], + &clearlooks_style->button_g4[state_type]); + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + if (area) + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw text Entry */ +void cl_draw_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + gboolean has_focus = GTK_WIDGET_HAS_FOCUS(widget); + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + + gtk_style_apply_default_background (style, window, TRUE, state_type, + area, x+1, y+1, width-2, height-2); + + + cl_rectangle_set_entry (&r, style, state_type, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND, + has_focus); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + x++; + y++; + width-=2; + height-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_optionmenu(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, GtkWidget *widget, + const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + GtkRequisition indicator_size; + GtkBorder indicator_spacing; + int line_pos; + + option_menu_get_props (widget, &indicator_size, &indicator_spacing); + + if (get_direction (widget) == GTK_TEXT_DIR_RTL) + line_pos = x + (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + style->xthickness; + else + line_pos = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness; + + cl_draw_button (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height); + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + line_pos, y + style->ythickness - 1, line_pos, + y + height - style->ythickness); + + gdk_draw_line (window, style->light_gc[state_type], + line_pos+1, y + style->ythickness - 1, line_pos+1, + y + height - style->ythickness); +} + + +void cl_draw_menuitem_button (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + int corner = CL_CORNER_NARROW; + GdkColor lower_color; + + shade (&style->base[GTK_STATE_SELECTED], &lower_color, 0.85); + + if (menubar) + { + height++; + corner = CL_CORNER_NONE; + r->bordergc = clearlooks_style->border_gc[CL_BORDER_UPPER]; + } + else + { + r->bordergc = clearlooks_style->spot3_gc; + } + + cl_rectangle_set_corners (r, corner, corner, corner, corner); + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->base[GTK_STATE_SELECTED], &lower_color); + + r->gradient_type = CL_GRADIENT_VERTICAL; + + r->fillgc = clearlooks_style->spot2_gc; + r->topleft = clearlooks_style->spot1_gc; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_draw_shadow (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); +} + +void cl_draw_menuitem_flat (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + GdkColor tmp; + + cl_rectangle_set_corners (r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + tmp = cl_gc_set_fg_color_shade (style->black_gc, style->colormap, + &style->base[GTK_STATE_PRELIGHT], 0.8); + + r->bordergc = style->black_gc; + r->fillgc = style->base_gc[GTK_STATE_PRELIGHT]; + + if (menubar) height++; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); + + gdk_gc_set_foreground (style->black_gc, &tmp); +} + +void cl_draw_menuitem_gradient (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + GdkColor tmp; + GdkColor lower_color; + + shade (&style->base[GTK_STATE_SELECTED], &lower_color, 0.8); + + cl_rectangle_set_corners (r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->base[GTK_STATE_SELECTED], &lower_color); + + r->gradient_type = CL_GRADIENT_VERTICAL; + + tmp = cl_gc_set_fg_color_shade (style->black_gc, style->colormap, + &style->base[GTK_STATE_PRELIGHT], 0.8); + + r->bordergc = style->black_gc; + r->fillgc = style->base_gc[GTK_STATE_PRELIGHT]; + + if (menubar) height++; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); + + gdk_gc_set_foreground (style->black_gc, &tmp); +} + +void cl_draw_treeview_header (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint columns = 0, column_index = -1, fill_width = width; + gboolean is_etree = strcmp("ETree", G_OBJECT_TYPE_NAME(widget->parent)) == 0; + gboolean resizable = TRUE; + + GdkGC *bottom = clearlooks_style->shade_gc[5]; + + if ( width < 2 || height < 2 ) + return; + + if (GTK_IS_TREE_VIEW (widget->parent)) + { + gtk_treeview_get_header_index (GTK_TREE_VIEW(widget->parent), + widget, &column_index, &columns, + &resizable); + } + else if (GTK_IS_CLIST (widget->parent)) + { + gtk_clist_get_header_index (GTK_CLIST(widget->parent), + widget, &column_index, &columns); + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[4], area); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[5], area); + } + + if (state_type != GTK_STATE_NORMAL) + fill_width-=2; + + gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, fill_width, height-(height/3)+1); + + draw_hgradient (window, style->bg_gc[state_type], style, + x, 1+y+height-(height/3), fill_width, height/3, + &style->bg[state_type], &clearlooks_style->inset_dark[state_type]); + + if (resizable || (column_index != columns-1)) + { + gdk_draw_line (window, clearlooks_style->shade_gc[4], x+width-2, y+4, x+width-2, y+height-5); + gdk_draw_line (window, clearlooks_style->shade_gc[0], x+width-1, y+4, x+width-1, y+height-5); + } + + /* left light line */ + if (column_index == 0) + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y+1, x, y+height-2); + + /* top light line */ + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x+width-1, y); + + /* bottom dark line */ + if (state_type == GTK_STATE_INSENSITIVE) + bottom = clearlooks_style->shade_gc[3]; + + + gdk_draw_line (window, bottom, x, y+height-1, x+width-1, y+height-1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[4], NULL); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[5], NULL); + } +} diff --git a/libs/clearlooks-older/clearlooks_draw.h b/libs/clearlooks-older/clearlooks_draw.h new file mode 100644 index 0000000000..a8cbb3732f --- /dev/null +++ b/libs/clearlooks-older/clearlooks_draw.h @@ -0,0 +1,159 @@ +#ifndef CLEARLOOKS_DRAW_H +#define CLEARLOOKS_DRAW_H + +#include +#include + +typedef struct +{ + GdkColor *from; + GdkColor *to; +} CLGradient; + +typedef enum +{ + CL_GRADIENT_NONE, + CL_GRADIENT_HORIZONTAL, + CL_GRADIENT_VERTICAL +} CLGradientType; + +typedef struct +{ + CLGradient fill_gradient; + CLGradient border_gradient; + + CLGradientType gradient_type; + + GdkGC *bordergc; + GdkGC *fillgc; + + guint8 corners[4]; + + GdkGC *topleft; /* top + left shadow */ + GdkGC *bottomright; /* bottom + right shadow */ + + GdkColor tmp_color; /* used for gradient */ +} CLRectangle; + +typedef enum /* DON'T CHANGE THE ORDER! */ +{ + CL_CORNER_TOPRIGHT, + CL_CORNER_BOTTOMRIGHT, + CL_CORNER_BOTTOMLEFT, + CL_CORNER_TOPLEFT +} CLCornerSide; + +typedef enum /* DON'T CHANGE THE ORDER! */ +{ + CL_BORDER_TOP, + CL_BORDER_RIGHT, + CL_BORDER_BOTTOM, + CL_BORDER_LEFT +} CLBorderType; + +typedef enum +{ + CL_CORNER_NONE = 0, + CL_CORNER_NARROW = 1, + CL_CORNER_ROUND = 2 +} CLCornerSharpness; + + + +CLRectangle *cl_rectangle_new(GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br); + +void cl_draw_rectangle (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_rectangle_set_color (CLGradient *g, GdkColor *color); +void cl_rectangle_set_gradient (CLGradient *g, GdkColor *from, GdkColor *to); + +void cl_rectangle_set_button (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, gboolean hasdefault, gboolean has_focus, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br); + +void cl_rectangle_set_entry (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br, + gboolean has_focus); + +void cl_draw_shadow(GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_rectangle_set_clip_rectangle (CLRectangle *r, GdkRectangle *area); +void cl_rectangle_reset_clip_rectangle (CLRectangle *r); + +void cl_set_corner_sharpness (const gchar *detail, GtkWidget *widget, CLRectangle *r); + + +void cl_rectangle_set_corners (CLRectangle *r, int tl, int tr, int bl, int br); + +void cl_rectangle_init (CLRectangle *r, GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br); + +void cl_rectangle_reset (CLRectangle *r, GtkStyle *style); + + +GdkPixmap* cl_progressbar_tile_new (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, gint height, gint offset); + +void cl_progressbar_fill (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, GdkGC *gc, + gint x, gint y, gint width, gint height, + guint8 offset, GdkRectangle *area); + +GdkColor cl_gc_set_fg_color_shade (GdkGC *gc, GdkColormap *colormap, + GdkColor *from, gfloat s); + +void cl_draw_spinbutton(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_button(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_combobox_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_combobox_button (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_menuitem_button (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_menuitem_flat (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_menuitem_gradient (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_treeview_header (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +#endif /* CLEARLOOKS_DRAW_H */ diff --git a/libs/clearlooks-older/clearlooks_rc_style.c b/libs/clearlooks-older/clearlooks_rc_style.c new file mode 100644 index 0000000000..1c5f2c495e --- /dev/null +++ b/libs/clearlooks-older/clearlooks_rc_style.c @@ -0,0 +1,392 @@ +/* Clearlooks theme engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor + * and by Alexander Larsson + * Modified by Richard Stellingwerff + */ + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +static void clearlooks_rc_style_init (ClearlooksRcStyle *style); +static void clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass); +static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle *rc_style); +static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner); +static void clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src); + + +static GtkRcStyleClass *parent_class; + +GType clearlooks_type_rc_style = 0; + +enum +{ + TOKEN_SPOTCOLOR = G_TOKEN_LAST + 1, + TOKEN_CONTRAST, + TOKEN_SUNKENMENU, + TOKEN_PROGRESSBARSTYLE, + TOKEN_MENUBARSTYLE, + TOKEN_MENUITEMSTYLE, + TOKEN_LISTVIEWITEMSTYLE +}; + +static struct + { + const gchar *name; + guint token; + } +theme_symbols[] = +{ + { "spotcolor", TOKEN_SPOTCOLOR }, + { "contrast", TOKEN_CONTRAST }, + { "sunkenmenubar", TOKEN_SUNKENMENU }, + { "progressbarstyle", TOKEN_PROGRESSBARSTYLE }, + { "menubarstyle", TOKEN_MENUBARSTYLE }, + { "menuitemstyle", TOKEN_MENUITEMSTYLE }, + { "listviewitemstyle", TOKEN_LISTVIEWITEMSTYLE } +}; + + +void +clearlooks_rc_style_register_type (GTypeModule *module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksRcStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_rc_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksRcStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_rc_style_init, + NULL + }; + + clearlooks_type_rc_style = g_type_module_register_type (module, + GTK_TYPE_RC_STYLE, + "ClearlooksRcStyle", + &object_info, 0); +} + +static void +clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc) +{ + clearlooks_rc->has_spot_color = FALSE; + clearlooks_rc->contrast = 1.0; + clearlooks_rc->sunkenmenubar = 1; + clearlooks_rc->progressbarstyle = 0; + clearlooks_rc->menubarstyle = 0; + clearlooks_rc->menuitemstyle = 1; + clearlooks_rc->listviewitemstyle = 1; +} + +static void +clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass) +{ + GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + rc_style_class->parse = clearlooks_rc_style_parse; + rc_style_class->create_style = clearlooks_rc_style_create_style; + rc_style_class->merge = clearlooks_rc_style_merge; +} + +static guint +theme_parse_color(GtkSettings *settings, + GScanner *scanner, + GdkColor *color) +{ + guint token; + + /* Skip 'blah_color' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + return gtk_rc_parse_color (scanner, color); +} + +static guint +theme_parse_contrast(GtkSettings *settings, + GScanner *scanner, + double *contrast) +{ + guint token; + + /* Skip 'contrast' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_FLOAT) + return G_TOKEN_FLOAT; + + *contrast = scanner->value.v_float; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_sunkenmenubar(GtkSettings *settings, + GScanner *scanner, + guint8 *sunken) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *sunken = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_progressbarstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *progressbarstyle) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *progressbarstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_menubarstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *menubarstyle) +{ + guint token; + + /* Skip 'menubarstyle' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *menubarstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_menuitemstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *menuitemstyle) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *menuitemstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_listviewitemstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *listviewitemstyle) +{ + guint token; + + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *listviewitemstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner) + +{ + static GQuark scope_id = 0; + ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style); + + guint old_scope; + guint token; + guint i; + + /* Set up a new scope in this scanner. */ + + if (!scope_id) + scope_id = g_quark_from_string("clearlooks_theme_engine"); + + /* If we bail out due to errors, we *don't* reset the scope, so the + * error messaging code can make sense of our tokens. + */ + old_scope = g_scanner_set_scope(scanner, scope_id); + + /* Now check if we already added our symbols to this scope + * (in some previous call to clearlooks_rc_style_parse for the + * same scanner. + */ + + if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name)) + { + g_scanner_freeze_symbol_table(scanner); + for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++) + g_scanner_scope_add_symbol(scanner, scope_id, + theme_symbols[i].name, + GINT_TO_POINTER(theme_symbols[i].token)); + g_scanner_thaw_symbol_table(scanner); + } + + /* We're ready to go, now parse the top level */ + + token = g_scanner_peek_next_token(scanner); + while (token != G_TOKEN_RIGHT_CURLY) + { + switch (token) + { + case TOKEN_SPOTCOLOR: + token = theme_parse_color(settings, scanner, &clearlooks_style->spot_color); + clearlooks_style->has_spot_color = TRUE; + break; + case TOKEN_CONTRAST: + token = theme_parse_contrast(settings, scanner, &clearlooks_style->contrast); + break; + case TOKEN_SUNKENMENU: + token = theme_parse_sunkenmenubar(settings, scanner, &clearlooks_style->sunkenmenubar); + break; + case TOKEN_PROGRESSBARSTYLE: + token = theme_parse_progressbarstyle(settings, scanner, &clearlooks_style->progressbarstyle); + break; + case TOKEN_MENUBARSTYLE: + token = theme_parse_menubarstyle(settings, scanner, &clearlooks_style->menubarstyle); + break; + case TOKEN_MENUITEMSTYLE: + token = theme_parse_menuitemstyle(settings, scanner, &clearlooks_style->menuitemstyle); + break; + case TOKEN_LISTVIEWITEMSTYLE: + token = theme_parse_listviewitemstyle(settings, scanner, &clearlooks_style->listviewitemstyle); + break; + default: + g_scanner_get_next_token(scanner); + token = G_TOKEN_RIGHT_CURLY; + break; + } + + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_peek_next_token(scanner); + } + + g_scanner_get_next_token(scanner); + + g_scanner_set_scope(scanner, old_scope); + + return G_TOKEN_NONE; +} + +static void +clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src) +{ + ClearlooksRcStyle *dest_w, *src_w; + + parent_class->merge (dest, src); + + if (!CLEARLOOKS_IS_RC_STYLE (src)) + return; + + src_w = CLEARLOOKS_RC_STYLE (src); + dest_w = CLEARLOOKS_RC_STYLE (dest); + + dest_w->contrast = src_w->contrast; + dest_w->sunkenmenubar = src_w->sunkenmenubar; + dest_w->progressbarstyle = src_w->progressbarstyle; + dest_w->menubarstyle = src_w->menubarstyle; + dest_w->menuitemstyle = src_w->menuitemstyle; + dest_w->listviewitemstyle = src_w->listviewitemstyle; + + if (src_w->has_spot_color) + { + dest_w->has_spot_color = TRUE; + dest_w->spot_color = src_w->spot_color; + } +} + + +/* Create an empty style suitable to this RC style + */ +static GtkStyle * +clearlooks_rc_style_create_style (GtkRcStyle *rc_style) +{ + return GTK_STYLE (g_object_new (CLEARLOOKS_TYPE_STYLE, NULL)); +} diff --git a/libs/clearlooks-older/clearlooks_rc_style.h b/libs/clearlooks-older/clearlooks_rc_style.h new file mode 100644 index 0000000000..bd8e0ca05d --- /dev/null +++ b/libs/clearlooks-older/clearlooks_rc_style.h @@ -0,0 +1,57 @@ +/* Clearlooks Theme Engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor + * and by Alexander Larsson + * Modified by Richard Stellingwerff + */ + +#include + +typedef struct _ClearlooksRcStyle ClearlooksRcStyle; +typedef struct _ClearlooksRcStyleClass ClearlooksRcStyleClass; + +extern GType clearlooks_type_rc_style; + +#define CLEARLOOKS_TYPE_RC_STYLE clearlooks_type_rc_style +#define CLEARLOOKS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyle)) +#define CLEARLOOKS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) +#define CLEARLOOKS_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) + +struct _ClearlooksRcStyle +{ + GtkRcStyle parent_instance; + + GdkColor spot_color; + gboolean has_spot_color; + double contrast; + guint8 sunkenmenubar; + guint8 progressbarstyle; + guint8 menubarstyle; + guint8 menuitemstyle; + guint8 listviewitemstyle; +}; + +struct _ClearlooksRcStyleClass +{ + GtkRcStyleClass parent_class; +}; + +void clearlooks_rc_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks-older/clearlooks_style.c b/libs/clearlooks-older/clearlooks_style.c new file mode 100644 index 0000000000..074f1604b1 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_style.c @@ -0,0 +1,2661 @@ +#include + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" +#include "clearlooks_draw.h" + +#include +#include + +#include "bits.c" +#include "support.h" +//#include "config.h" + +/* #define DEBUG 1 */ + +#define SCALE_SIZE 5 + +#define DETAIL(xx) ((detail) && (!strcmp(xx, detail))) +#define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue) + +#define DRAW_ARGS GtkStyle *style, \ + GdkWindow *window, \ + GtkStateType state_type, \ + GtkShadowType shadow_type, \ + GdkRectangle *area, \ + GtkWidget *widget, \ + const gchar *detail, \ + gint x, \ + gint y, \ + gint width, \ + gint height + +static GdkGC *realize_color (GtkStyle * style, GdkColor * color); +static GtkStyleClass *parent_class; +static GList *progressbars = NULL; +static gint8 pboffset = 10; +static int timer_id = 0; + +static void cl_progressbar_remove (gpointer data) +{ + if (g_list_find (progressbars, data) == NULL) + return; + + progressbars = g_list_remove (progressbars, data); + g_object_unref (data); + + if (g_list_first(progressbars) == NULL) { + g_source_remove(timer_id); + timer_id = 0; + } +} + +static void update_progressbar (gpointer data, gpointer user_data) +{ + gfloat fraction; + + if (data == NULL) + return; + + fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (data)); + + /* update only if not filled */ + if (fraction < 1.0) + gtk_widget_queue_resize ((GtkWidget*)data); + + if (fraction >= 1.0 || GTK_PROGRESS (data)->activity_mode) + cl_progressbar_remove (data); +} + +static gboolean timer_func (gpointer data) +{ + g_list_foreach (progressbars, update_progressbar, NULL); + if (--pboffset < 0) pboffset = 9; + return (g_list_first(progressbars) != NULL); +} + +static gboolean cl_progressbar_known(gconstpointer data) +{ + return (g_list_find (progressbars, data) != NULL); +} + + +static void cl_progressbar_add (gpointer data) +{ + if (!GTK_IS_PROGRESS_BAR (data)) + return; + + progressbars = g_list_append (progressbars, data); + + g_object_ref (data); + g_signal_connect ((GObject*)data, "unrealize", G_CALLBACK (cl_progressbar_remove), data); + + if (timer_id == 0) + timer_id = g_timeout_add (100, timer_func, NULL); +} + +static GdkColor * +clearlooks_get_spot_color (ClearlooksRcStyle *clearlooks_rc) +{ + GtkRcStyle *rc = GTK_RC_STYLE (clearlooks_rc); + + if (clearlooks_rc->has_spot_color) + return &clearlooks_rc->spot_color; + else + return &rc->base[GTK_STATE_SELECTED]; +} + +/**************************************************************************/ + +/* used for optionmenus... */ +static void +draw_tab (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ +#define ARROW_SPACE 2 +#define ARROW_LINE_HEIGHT 2 +#define ARROW_LINE_WIDTH 5 + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GtkRequisition indicator_size; + GtkBorder indicator_spacing; + gint arrow_height; + + option_menu_get_props (widget, &indicator_size, &indicator_spacing); + + indicator_size.width += (indicator_size.width % 2) - 1; + arrow_height = indicator_size.width / 2 + 2; + + x += (width - indicator_size.width) / 2; + y += height/2; + + if (state_type == GTK_STATE_INSENSITIVE) + { + draw_arrow (window, style->light_gc[state_type], area, + GTK_ARROW_UP, 1+x, 1+y-arrow_height, + indicator_size.width, arrow_height); + + draw_arrow (window, style->light_gc[state_type], area, + GTK_ARROW_DOWN, 1+x, 1+y+1, + indicator_size.width, arrow_height); + } + + draw_arrow (window, style->fg_gc[state_type], area, + GTK_ARROW_UP, x, y-arrow_height, + indicator_size.width, arrow_height); + + draw_arrow (window, style->fg_gc[state_type], area, + GTK_ARROW_DOWN, x, y+1, + indicator_size.width, arrow_height); +} + +static void +clearlooks_draw_arrow (GtkStyle *style, + GdkWindow *window, + GtkStateType state, + GtkShadowType shadow, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint original_width, original_x; + GdkGC *gc; + + sanitize_size (window, &width, &height); + + if (is_combo_box (widget)) + { + width = 7; + height = 5; + x+=2; + y+=4; + if (state == GTK_STATE_INSENSITIVE) + { + draw_arrow (window, style->light_gc[state], area, + GTK_ARROW_UP, 1+x, 1+y-height, + width, height); + + draw_arrow (window, style->light_gc[state], area, + GTK_ARROW_DOWN, 1+x, 1+y+1, + width, height); + } + + draw_arrow (window, style->fg_gc[state], area, + GTK_ARROW_UP, x, y-height, + width, height); + + draw_arrow (window, style->fg_gc[state], area, + GTK_ARROW_DOWN, x, y+1, + width, height); + + return; + } + + original_width = width; + original_x = x; + + /* Make spinbutton arrows and arrows in menus + * slightly larger to get the right pixels drawn */ + if (DETAIL ("spinbutton")) + height += 1; + + if (DETAIL("menuitem")) + { + width = 6; + height = 7; + } + + /* Compensate arrow position for "sunken" look */ + if (DETAIL ("spinbutton") && arrow_type == GTK_ARROW_DOWN && + style->xthickness > 2 && style->ythickness > 2) + y -= 1; + + if (widget && widget->parent && GTK_IS_COMBO (widget->parent->parent)) + { + width -= 2; + height -=2; + x++; + } + + calculate_arrow_geometry (arrow_type, &x, &y, &width, &height); + + if (DETAIL ("menuitem")) + x = original_x + original_width - width; + + if (DETAIL ("spinbutton") && (arrow_type == GTK_ARROW_DOWN)) + y += 1; + + if (state == GTK_STATE_INSENSITIVE) + draw_arrow (window, style->light_gc[state], area, arrow_type, x + 1, y + 1, width, height); + + gc = style->fg_gc[state]; + + draw_arrow (window, gc, area, arrow_type, x, y, width, height); +} + + +static void +draw_flat_box (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (detail && + clearlooks_style->listviewitemstyle == 1 && + state_type == GTK_STATE_SELECTED && ( + !strncmp ("cell_even", detail, strlen ("cell_even")) || + !strncmp ("cell_odd", detail, strlen ("cell_odd")))) + { + GdkGC *gc; + GdkColor lower_color; + GdkColor *upper_color; + + if (GTK_WIDGET_HAS_FOCUS (widget)) + { + gc = style->base_gc[state_type]; + upper_color = &style->base[state_type]; + } + else + { + gc = style->base_gc[GTK_STATE_ACTIVE]; + upper_color = &style->base[GTK_STATE_ACTIVE]; + } + + if (GTK_IS_TREE_VIEW (widget) && 0) + { + GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); + + if (gtk_tree_selection_count_selected_rows (sel) > 1) + { + parent_class->draw_flat_box (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height); + return; + } + } + + shade (upper_color, &lower_color, 0.8); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + draw_hgradient (window, gc, style, + x, y, width, height, upper_color, &lower_color); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); + } + else + { + parent_class->draw_flat_box (style, window, state_type, + shadow_type, + area, widget, detail, + x, y, width, height); + } +} +/**************************************************************************/ + +static void +draw_shadow (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + + GdkGC *outer_gc = clearlooks_style->shade_gc[4]; + GdkGC *gc1 = NULL; + GdkGC *gc2 = NULL; + gint thickness_light; + gint thickness_dark; + gboolean interior_focus = FALSE; + +#if DEBUG + printf("draw_shadow: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + if (widget == NULL) + { + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + return; + } + + if ((width == -1) && (height == -1)) + gdk_window_get_size (window, &width, &height); + else if (width == -1) + gdk_window_get_size (window, &width, NULL); + else if (height == -1) + gdk_window_get_size (window, NULL, &height); + + cl_rectangle_reset (&r, style); + + if (DETAIL ("frame") && widget->parent && + GTK_IS_STATUSBAR (widget->parent)) + { + gtk_style_apply_default_background (style, window,widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + } + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + x, y, x + width, y); + gdk_draw_line (window, clearlooks_style->shade_gc[0], + x, y + 1, x + width, y + 1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + } + } + else if (detail && !strcmp (detail, "entry")) + { + if ( widget->parent && (GTK_IS_COMBO_BOX_ENTRY (widget->parent) || + GTK_IS_SPIN_BUTTON(widget) || + GTK_IS_COMBO (widget->parent))) + { + cl_draw_combobox_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height); + } + else + { + cl_draw_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height); + } + } + else if (DETAIL ("viewport") || DETAIL ("scrolled_window")) + { + gdk_draw_rectangle (window, clearlooks_style->shade_gc[4], FALSE, + x, y, width - 1, height - 1); + } + else + { + if (DETAIL ("menuitem")) + outer_gc = clearlooks_style->spot3_gc; + else + outer_gc = clearlooks_style->shade_gc[4]; + + if (shadow_type == GTK_SHADOW_IN) + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + else if (shadow_type == GTK_SHADOW_OUT) + { + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + gdk_draw_line (window, style->light_gc[state_type], + x+1, y+1, x+width-2, y+1); + gdk_draw_line (window, style->light_gc[state_type], + x+1, y+1, x+1, y+height-2); + } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3]; + GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0]; + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = a; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + + r.bordergc = b; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0]; + GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3]; + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = a; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + + r.bordergc = b; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else + parent_class->draw_shadow (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height); + } +} + +#define GDK_RECTANGLE_SET(rect,a,b,c,d) rect.x = a; \ + rect.y = b; \ + rect.width = c; \ + rect.height = d; + + +static void +draw_box_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + + GdkRegion *area_region = NULL, + *gap_region = NULL; + GdkRectangle light_rect; + GdkRectangle dark_rect; + +#if DEBUG + printf("draw_box_gap: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + cl_rectangle_reset (&r, style); + + r.bordergc = clearlooks_style->shade_gc[5]; + + r.topleft = style->light_gc[state_type]; + r.bottomright = clearlooks_style->shade_gc[1]; + + if (area) + area_region = gdk_region_rectangle (area); + else + { + GdkRectangle tmp = { x, y, width, height }; + area_region = gdk_region_rectangle (&tmp); + } + + switch (gap_side) + { + case GTK_POS_TOP: + { + GdkRectangle rect = { x+gap_x+1, y, gap_width-2, 2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y, x+gap_x+1, y+1); + GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y, x+gap_x+gap_width-2, y); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + break; + } + case GTK_POS_BOTTOM: + { + GdkRectangle rect = { x+gap_x+1, y+height-2, gap_width-2, 2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y+height-2, x+gap_x+1, y+height-1); + GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y+height-2, x+gap_x+gap_width-2, y+height-1); + + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + + break; + } + case GTK_POS_LEFT: + { + GdkRectangle rect = { x, y+gap_x+1, 2, gap_width-2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x, y+gap_x+1, x+1, y+gap_x+1); + GDK_RECTANGLE_SET (dark_rect, x, y+gap_x+gap_width-2, x, y+gap_x+gap_width-2); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + break; + } + case GTK_POS_RIGHT: + { + GdkRectangle rect = { x+width-2, y+gap_x+1, 2, gap_width-2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+width-2, y+gap_x+1, x+width-1, y+gap_x+1); + GDK_RECTANGLE_SET (dark_rect, x+width-2, y+gap_x+gap_width-2, x+width-1, y+gap_x+gap_width-2); + + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + break; + } + } + + gdk_region_subtract (area_region, gap_region); + + gdk_gc_set_clip_region (r.bordergc, area_region); + gdk_gc_set_clip_region (r.topleft, area_region); + gdk_gc_set_clip_region (r.bottomright, area_region); + + gdk_region_destroy (area_region); + gdk_region_destroy (gap_region); + + gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, width, height); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + gdk_gc_set_clip_region (r.bordergc, NULL); + gdk_gc_set_clip_region (r.topleft, NULL); + gdk_gc_set_clip_region (r.bottomright, NULL); + + /* it's a semi hack */ + gdk_draw_line (window, style->light_gc[state_type], + light_rect.x, light_rect.y, + light_rect.width, light_rect.height); + + gdk_draw_line (window, clearlooks_style->shade_gc[1], + dark_rect.x, dark_rect.y, + dark_rect.width, dark_rect.height); +} + +/**************************************************************************/ + +static void +draw_extension (DRAW_ARGS, GtkPositionType gap_side) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + CLRectangle r; + +#if DEBUG + printf("draw_extension: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (DETAIL ("tab")) + { + GdkRectangle new_area; + GdkColor tmp_color; + + cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + shade (&style->bg[state_type], &tmp_color, 1.08); + else + shade (&style->bg[state_type], &tmp_color, 1.05); + + if (area) + { + new_area = *area; + } + else + { + new_area.x = x; + new_area.y = y; + new_area.width = width; + new_area.height = height; + } + + switch (gap_side) + { + case GTK_POS_BOTTOM: + height+=2; + new_area.y = y; + new_area.height = height-2; + r.gradient_type = CL_GRADIENT_VERTICAL; + cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + break; + case GTK_POS_TOP: + y-=2; + height+=2; + new_area.y = y+2; + new_area.height = height; + r.gradient_type = CL_GRADIENT_VERTICAL; + cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type], + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]); + break; + case GTK_POS_LEFT: + x-=2; + width+=2; + new_area.x = x+2; + new_area.width = width; + r.gradient_type = CL_GRADIENT_HORIZONTAL; + cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type], + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]); + break; + case GTK_POS_RIGHT: + width+=2; + new_area.x = x; + new_area.width = width-2; + r.gradient_type = CL_GRADIENT_HORIZONTAL; + cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + break; + } + + r.topleft = style->light_gc[state_type]; + r.bottomright = (state_type == GTK_STATE_NORMAL) ? clearlooks_style->shade_gc[1] : NULL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + /* draw the selection stripe */ + if (state_type != GTK_STATE_ACTIVE) { + cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL); + r.fillgc = clearlooks_style->spot2_gc; + + switch (gap_side) + { + case GTK_POS_BOTTOM: + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2); + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, width, 3, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_TOP: + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3); + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y + height - 3, width, 3, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_LEFT: + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3); + r.gradient_type = CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x + width - 3, y, 3, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_RIGHT: + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2); + r.gradient_type = CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, 3, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + } + } + + + } + else + { + parent_class->draw_extension (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side); + } +} + + +/**************************************************************************/ + +static void +draw_handle (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint xx, yy; + gint xthick, ythick; + GdkGC *light_gc, *dark_gc; + GdkRectangle rect; + GdkRectangle dest; + gint intersect; + gint h; + int i; + int n_lines; + int offset; + +#if DEBUG + printf("draw_handle: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (state_type == GTK_STATE_PRELIGHT) + gtk_style_apply_default_background (style, window, + widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + /* orientation is totally bugged, but this actually works... */ + orientation = (width > height) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; + + if (!strcmp (detail, "paned")) + { + /* we want to ignore the shadow border in paned widgets */ + xthick = 0; + ythick = 0; + } + else + { + xthick = style->xthickness; + ythick = style->ythickness; + } + + if ( ((DETAIL ("handlebox") && widget && GTK_IS_HANDLE_BOX (widget)) || DETAIL ("dockitem")) && + orientation == GTK_ORIENTATION_VERTICAL ) + { + /* The line in the toolbar */ + + light_gc = style->light_gc[state_type]; + dark_gc = clearlooks_style->shade_gc[3]; + + if (area) + { + gdk_gc_set_clip_rectangle (light_gc, area); + gdk_gc_set_clip_rectangle (dark_gc, area); + } + + if (area) + { + gdk_gc_set_clip_rectangle (light_gc, NULL); + gdk_gc_set_clip_rectangle (dark_gc, NULL); + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + } + + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x + width, y); + gdk_draw_line (window, clearlooks_style->shade_gc[3], x, y + height - 1, x + width, y + height - 1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + } + } + + light_gc = clearlooks_style->shade_gc[0]; + dark_gc = clearlooks_style->shade_gc[4]; + + rect.x = x + xthick; + rect.y = y + ythick; + rect.width = width - (xthick * 2); + rect.height = height - (ythick * 2); + + if (area) + intersect = gdk_rectangle_intersect (area, &rect, &dest); + else + { + intersect = TRUE; + dest = rect; + } + + if (!intersect) + return; + + gdk_gc_set_clip_rectangle (light_gc, &dest); + gdk_gc_set_clip_rectangle (dark_gc, &dest); + + n_lines = (!strcmp (detail, "paned")) ? 21 : 11; + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + h = width - 2 * xthick; + h = MAX (3, h - 6); + + xx = x + (width - h) / 2; + offset = (height - 2*ythick - 2*n_lines)/2 + 1; + if (offset < 0) + offset = 0; + + for (i = 0, yy = y + ythick + offset; yy <= (y + height - ythick - 1) && i < n_lines; yy += 2, i++) + { + gdk_draw_line (window, dark_gc, xx, yy, xx + h, yy); + gdk_draw_line (window, light_gc, xx, yy + 1, xx + h, yy + 1); + } + } + else + { + h = height - 2 * ythick; + h = MAX (3, h - 6); + + yy = y + (height - h) / 2; + offset = (width - 2*xthick - 2*n_lines)/2 + 1; + if (offset < 0) + offset = 0; + + for (i = 0, xx = x + xthick + offset; i < n_lines; xx += 2, i++) + { + gdk_draw_line (window, dark_gc, xx, yy, xx, yy + h); + gdk_draw_line (window, light_gc, xx + 1, yy, xx + 1, yy + h); + } + } + + gdk_gc_set_clip_rectangle (light_gc, NULL); + gdk_gc_set_clip_rectangle (dark_gc, NULL); +} + +/**************************************************************************/ + +static void +draw_box (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + gboolean false_size = FALSE; + +#ifdef DEBUG + printf("draw_box: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (style != NULL); + g_return_if_fail (window != NULL); + + if (width == -1 || height == -1) + false_size = TRUE; + + if ((width == -1) && (height == -1)) + gdk_window_get_size (window, &width, &height); + else if (width == -1) + gdk_window_get_size (window, &width, NULL); + else if (height == -1) + gdk_window_get_size (window, NULL, &height); + + cl_rectangle_reset (&r, style); + + if (widget == NULL) + return; + + /* listview headers */ + if (widget && DETAIL ("button") && widget->parent && + (GTK_IS_TREE_VIEW(widget->parent) || + GTK_IS_CLIST (widget->parent) || + strcmp(G_OBJECT_TYPE_NAME (widget->parent), "ETree") == 0)) + { + cl_draw_treeview_header (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + } + else if (detail && (!strcmp (detail, "button") || + !strcmp (detail, "buttondefault"))) + { + if (GTK_IS_COMBO_BOX_ENTRY(widget->parent) || GTK_IS_COMBO(widget->parent)) + { + cl_draw_combobox_button (style, window, state_type, shadow_type, + area, widget, + detail, x, y, width, height); + } + else + { + cl_draw_button (style, window, state_type, shadow_type, area, widget, + detail, x, y, width, height); + } + } + else if (detail && ( + !strcmp (detail, "spinbutton_up") || + !strcmp (detail, "spinbutton_down") || + !strcmp (detail, "spinbutton"))) + { + cl_draw_spinbutton (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + } + else if (detail && ( + !strcmp (detail, "hscale") || !strcmp (detail, "vscale"))) + { + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (!strcmp (detail, "hscale") || !strcmp (detail, "vscale")) + { + r.fill_gradient.to = &clearlooks_style->shade[2]; + r.bottomright = clearlooks_style->shade_gc[2]; + } + + cl_set_corner_sharpness (detail, widget, &r); + + if (!strcmp (detail, "spinbutton_up")) + { + r.border_gradient.to = r.border_gradient.from; + height++; + gtk_style_apply_default_background (style, window, FALSE, state_type, + area, x, y, width, height); + } + else if (!strcmp (detail, "spinbutton_down")) + { + r.border_gradient.to = r.border_gradient.from; + gtk_style_apply_default_background (style, window, FALSE, state_type, + area, x, y, width, height); + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-2, height-2, &r); + cl_draw_shadow (window, widget, style, x+1, y+1, width-2, height-2, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough") && GTK_IS_PROGRESS_BAR (widget)) + { + GdkPoint points[4] = { {x,y}, {x+width-1,y}, {x,y+height-1}, {x+width-1,y+height-1} }; + + gdk_draw_points (window, style->bg_gc[state_type], points, 4); + + r.bordergc = clearlooks_style->shade_gc[5]; + r.fillgc = clearlooks_style->shade_gc[2]; + + cl_rectangle_set_corners (&r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough") && + (GTK_IS_VSCALE (widget) || GTK_IS_HSCALE (widget))) + { + GdkGC *inner = clearlooks_style->shade_gc[3], + *outer = clearlooks_style->shade_gc[5], + *shadow = clearlooks_style->shade_gc[4]; + GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)), + lower_color; + + GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget)); + + GtkOrientation orientation = GTK_RANGE (widget)->orientation; + + gint fill_size = (orientation ? height : width) * + (1 / ((adjustment->upper - adjustment->lower) / + (adjustment->value - adjustment->lower))); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + y += (height - SCALE_SIZE) / 2; + height = SCALE_SIZE; + } + else + { + x += (width - SCALE_SIZE) / 2; + width = SCALE_SIZE; + } + + if (state_type == GTK_STATE_INSENSITIVE) + { + outer = clearlooks_style->shade_gc[4]; + inner = clearlooks_style->shade_gc[2]; + shadow = clearlooks_style->shade_gc[3]; + } + + cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE ); + + r.topleft = shadow; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + /* DRAW FILL */ + shade (&upper_color, &lower_color, 1.3); + + r.bordergc = clearlooks_style->spot3_gc; + r.fillgc = style->bg_gc[state_type]; + + r.gradient_type = (orientation == GTK_ORIENTATION_HORIZONTAL ) ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color); + + cl_rectangle_set_clip_rectangle (&r, area); + if (orientation == GTK_ORIENTATION_HORIZONTAL && fill_size > 1) + { + if (gtk_range_get_inverted(GTK_RANGE(widget)) != (get_direction(widget) == GTK_TEXT_DIR_RTL)) + cl_draw_rectangle (window, widget, style, x+width-fill_size, y, fill_size, height, &r); + else + cl_draw_rectangle (window, widget, style, x, y, fill_size, height, &r); + } + else if (fill_size > 1) + { + if (gtk_range_get_inverted (GTK_RANGE (widget))) + cl_draw_rectangle (window, widget, style, x, y+height-fill_size, width, fill_size, &r); + else + cl_draw_rectangle (window, widget, style, x, y, width, fill_size, &r); + } + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough")) + { + GdkGC *inner = clearlooks_style->shade_gc[3], + *outer = clearlooks_style->shade_gc[5]; + + cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE ); + + if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_VERTICAL) + { + y+=1; + height-=2; + } + else + { + x+=1; + width-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (detail && (!strcmp (detail, "vscrollbar") || + !strcmp (detail, "hscrollbar") || + !strcmp (detail, "stepper"))) + { + ClScrollButtonType button_type = CL_SCROLLBUTTON_OTHER; + gboolean horizontal = TRUE; + + if (GTK_IS_VSCROLLBAR(widget)) + { + if (y == widget->allocation.y) + button_type = CL_SCROLLBUTTON_BEGIN; + else if (y+height == widget->allocation.y+widget->allocation.height) + button_type = CL_SCROLLBUTTON_END; + + horizontal = FALSE; + } + else if (GTK_IS_HSCROLLBAR(widget)) + { + if (x == widget->allocation.x) + button_type = CL_SCROLLBUTTON_BEGIN; + else if (x+width == widget->allocation.x+widget->allocation.width) + button_type = CL_SCROLLBUTTON_END; + } + + cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, 0,0,0,0); + + cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL); + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type], + &clearlooks_style->inset_dark[state_type]); + + + r.gradient_type = horizontal ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + r.bottomright = clearlooks_style->shade_gc[1]; + r.border_gradient.to = r.border_gradient.from; + + if (button_type == CL_SCROLLBUTTON_OTHER) + { + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else if (button_type == CL_SCROLLBUTTON_BEGIN) + { + if (horizontal) + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + else + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else + { + if (horizontal) + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + else + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + } + else if (DETAIL ("slider")) + { + if (DETAIL("slider") && widget && GTK_IS_RANGE (widget)) + { + GtkAdjustment *adj = GTK_RANGE (widget)->adjustment; + + if (adj->value <= adj->lower && + (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b)) + { + if (GTK_IS_VSCROLLBAR (widget)) + { + y-=1; + height+=1; + } + else if (GTK_IS_HSCROLLBAR (widget)) + { + x-=1; + width+=1; + } + } + if (adj->value >= adj->upper - adj->page_size && + (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d)) + { + if (GTK_IS_VSCROLLBAR (widget)) + height+=1; + else if (GTK_IS_HSCROLLBAR (widget)) + width+=1; + } + } + + cl_rectangle_set_button (&r, style, state_type, FALSE, GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.gradient_type = GTK_IS_HSCROLLBAR (widget) ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type], + &clearlooks_style->inset_dark[state_type]); + + r.bottomright = clearlooks_style->shade_gc[1]; + r.border_gradient.to = r.border_gradient.from; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (detail && !strcmp (detail, "optionmenu")) /* supporting deprecated */ + { + cl_draw_optionmenu(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height); + } + else if (DETAIL ("menuitem")) + { + if (clearlooks_style->menuitemstyle == 0) + { + cl_draw_menuitem_flat (window, widget, style, area, state_type, + x, y, width, height, &r); + } + else if (clearlooks_style->menuitemstyle == 1) + { + cl_draw_menuitem_gradient (window, widget, style, area, state_type, + x, y, width, height, &r); + } + else + { + cl_draw_menuitem_button (window, widget, style, area, state_type, + x, y, width, height, &r); + } + } + else if (DETAIL ("menubar") && (clearlooks_style->sunkenmenubar || clearlooks_style->menubarstyle > 0)) + { + GdkGC *dark = clearlooks_style->shade_gc[2]; + GdkColor upper_color, lower_color; + + /* don't draw sunken menubar on gnome panel + IT'S A HACK! HORRIBLE HACK! HIDEOUS HACK! + BUT IT WORKS FOR ME(tm)! */ + if (widget->parent && + strcmp(G_OBJECT_TYPE_NAME (widget->parent), "PanelWidget") == 0) + return; + + shade(&style->bg[state_type], &upper_color, 1.0); + shade(&style->bg[state_type], &lower_color, 0.95); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.fillgc = style->bg_gc[state_type]; + r.bordergc = clearlooks_style->shade_gc[2]; + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->shade[2], + &clearlooks_style->shade[3]); + cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color); + + /* make vertical and top borders invisible for style 2 */ + if (clearlooks_style->menubarstyle == 2) { + x--; width+=2; + y--; height+=1; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("menu") && widget->parent && + GDK_IS_WINDOW (widget->parent->window)) + { + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = clearlooks_style->border_gc[CL_BORDER_UPPER]; + r.topleft = style->light_gc[state_type]; + r.bottomright = clearlooks_style->shade_gc[1]; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + return; + } + else if (DETAIL ("bar") && widget && GTK_IS_PROGRESS_BAR (widget)) + { + GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)), + lower_color, + prev_foreground; + gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode; + +#ifdef HAVE_ANIMATION + if (!activity_mode && gtk_progress_bar_get_fraction (widget) != 1.0 && + !cl_progressbar_known((gconstpointer)widget)) + { + cl_progressbar_add ((gpointer)widget); + } +#endif + cl_progressbar_fill (window, widget, style, style->black_gc, + x, y, width, height, +#ifdef HAVE_ANIMATION + activity_mode ? 0 : pboffset, +#else + 0, +#endif + area); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = clearlooks_style->spot3_gc; + r.topleft = clearlooks_style->spot2_gc; + + prev_foreground = cl_gc_set_fg_color_shade (clearlooks_style->spot2_gc, + style->colormap, + &clearlooks_style->spot2, + 1.2); + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + gdk_gc_set_foreground (clearlooks_style->spot2_gc, &prev_foreground); + } + + else if ( widget && (DETAIL ("menubar") || DETAIL ("toolbar") || DETAIL ("dockitem_bin") || DETAIL ("handlebox_bin")) && shadow_type != GTK_SHADOW_NONE) /* Toolbars and menus */ + { + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + } + + gtk_style_apply_default_background (style, window, + widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + /* we only want the borders on horizontal toolbars */ + if ( DETAIL ("menubar") || height < 2*width ) { + if (!DETAIL ("menubar")) + gdk_draw_line (window, clearlooks_style->shade_gc[0], + x, y, x + width, y); /* top */ + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + x, y + height - 1, x + width, y + height - 1); /* bottom */ + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + } + } + else + { + parent_class->draw_box (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + } +} + +/**************************************************************************/ + +static void +ensure_check_pixmaps (GtkStyle *style, + GtkStateType state, + GdkScreen *screen, + gboolean treeview) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style); + GdkPixbuf *check, *base, *inconsistent, *composite; + GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc); + + if (clearlooks_style->check_pixmap_nonactive[state] != NULL) + return; + + if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) { + check = generate_bit (check_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + inconsistent = generate_bit (check_inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + } else { + check = generate_bit (check_alpha, &style->text[state], 1.0); + inconsistent = generate_bit (check_inconsistent_alpha, &style->text[state], 1.0); + } + + if (state == GTK_STATE_ACTIVE && !treeview) + base = generate_bit (check_base_alpha, &style->bg[state], 1.0); + else + base = generate_bit (check_base_alpha, &style->base[GTK_STATE_NORMAL], 1.0); + + if (treeview) + composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0); + else + composite = generate_bit (NULL, &clearlooks_style->shade[5], 1.0); + + gdk_pixbuf_composite (base, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_nonactive[state] = + pixbuf_to_pixmap (style, composite, screen); + + gdk_pixbuf_composite (check, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_active[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + + composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0); + + gdk_pixbuf_composite (base, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + gdk_pixbuf_composite (inconsistent, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_inconsistent[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + g_object_unref (base); + g_object_unref (check); + g_object_unref (inconsistent); +} + +static void +draw_check (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *gc = style->base_gc[state_type]; + GdkPixmap *pixmap; + gboolean treeview; + + if (DETAIL ("check")) /* Menu item */ + { + parent_class->draw_check (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + return; + } + + treeview = widget && GTK_IS_TREE_VIEW(widget); + ensure_check_pixmaps (style, state_type, gtk_widget_get_screen (widget), treeview); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (shadow_type == GTK_SHADOW_IN) + pixmap = clearlooks_style->check_pixmap_active[state_type]; + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + pixmap = clearlooks_style->check_pixmap_inconsistent[state_type]; + else + pixmap = clearlooks_style->check_pixmap_nonactive[state_type]; + + x += (width - CHECK_SIZE)/2; + y += (height - CHECK_SIZE)/2; + + gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, CHECK_SIZE, CHECK_SIZE); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +/**************************************************************************/ +static void +draw_slider (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *shade_gc = clearlooks_style->shade_gc[4]; + GdkGC *white_gc = clearlooks_style->shade_gc[0]; + int x1, y1; + +#if DEBUG + printf("draw_slider: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + gtk_paint_box (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + + if ((orientation == GTK_ORIENTATION_VERTICAL && height < 20) || + (orientation == GTK_ORIENTATION_HORIZONTAL && width < 20)) + return; + + if (detail && strcmp ("slider", detail) == 0) + { + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, area); + gdk_gc_set_clip_rectangle (white_gc, area); + } + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + x1 = x + width / 2 - 4; + y1 = y + (height - 6) / 2; + gdk_draw_line (window, shade_gc, x1, y1, x1, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 1, y1, x1 + 1, y1 + 6); + gdk_draw_line (window, shade_gc, x1 + 3, y1, x1 + 3, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 3 + 1, y1, x1 + 3 + 1, y1 + 6); + gdk_draw_line (window, shade_gc, x1 + 3*2, y1, x1 + 3*2, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 3*2 + 1, y1, x1 + 3*2 + 1, y1 + 6); + } + else + { + x1 = x + (width - 6) / 2; + y1 = y + height / 2 - 4; + gdk_draw_line (window, shade_gc, x1 + 6, y1, x1, y1); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 1, x1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3, x1, y1 + 3); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 3 + 1, x1, y1 + 3 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3*2, x1, y1 + 3*2); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 3*2 + 1, x1, y1 + 3*2 + 1); + } + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, NULL); + gdk_gc_set_clip_rectangle (white_gc, NULL); + } + } + else if (detail && (strcmp ("hscale", detail) == 0 || strcmp ("vscale", detail) == 0)) + { + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, area); + gdk_gc_set_clip_rectangle (white_gc, area); + } + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + x1 = x + width / 2 - 3; + y1 = y + (height - 7) / 2; + gdk_draw_line (window, shade_gc, x1 + 0, y1 + 5, x1 + 0, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 1, y1 + 5, x1 + 1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 3, y1 + 5, x1 + 3, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 4, y1 + 5, x1 + 4, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 5, x1 + 6, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 7, y1 + 5, x1 + 7, y1 + 1); + } + else + { + x1 = x + (width - 7) / 2; + y1 = y + height / 2 - 3; + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 0, x1 + 1, y1 + 0); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 1, x1 + 1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 3, x1 + 1, y1 + 3); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 4, x1 + 1, y1 + 4); + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 6, x1 + 1, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 7, x1 + 1, y1 + 7); + } + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, NULL); + gdk_gc_set_clip_rectangle (white_gc, NULL); + } + } +} + +/**************************************************************************/ +static void +ensure_radio_pixmaps (GtkStyle *style, + GtkStateType state, + GdkScreen *screen) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style); + GdkPixbuf *dot, *circle, *outline, *inconsistent, *composite; + GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc); + GdkColor *composite_color; + + if (clearlooks_style->radio_pixmap_nonactive[state] != NULL) + return; + + if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) { + dot = colorize_bit (dot_intensity, dot_alpha, &style->text[GTK_STATE_NORMAL]); + inconsistent = generate_bit (inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + } else { + dot = colorize_bit (dot_intensity, dot_alpha, &style->text[state]); + inconsistent = generate_bit (inconsistent_alpha, &style->text[state], 1.0); + } + + outline = generate_bit (outline_alpha, &clearlooks_style->shade[5], 1.0); + + if (clearlooks_style->radio_pixmap_mask == NULL) + { + gdk_pixbuf_render_pixmap_and_mask (outline, + NULL, + &clearlooks_style->radio_pixmap_mask, + 1); + } + + if (state == GTK_STATE_ACTIVE) + { + composite_color = &style->bg[GTK_STATE_PRELIGHT]; + circle = generate_bit (circle_alpha, &style->bg[state], 1.0); + } + else + { + composite_color = &style->bg[state]; + circle = generate_bit (circle_alpha, &style->base[GTK_STATE_NORMAL], 1.0); + } + + composite = generate_bit (NULL, composite_color, 1.0); + + gdk_pixbuf_composite (outline, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + gdk_pixbuf_composite (circle, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_nonactive[state] = + pixbuf_to_pixmap (style, composite, screen); + + gdk_pixbuf_composite (dot, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_active[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + + composite = generate_bit (NULL, composite_color,1.0); + + gdk_pixbuf_composite (outline, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + gdk_pixbuf_composite (circle, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + gdk_pixbuf_composite (inconsistent, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_inconsistent[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + g_object_unref (circle); + g_object_unref (dot); + g_object_unref (inconsistent); + g_object_unref (outline); +} + +static void +draw_option (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *gc = style->base_gc[state_type]; + GdkPixmap *pixmap; + + if (DETAIL ("option")) /* Menu item */ + { + parent_class->draw_option (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + return; + } + + ensure_radio_pixmaps (style, state_type, gtk_widget_get_screen (widget)); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (shadow_type == GTK_SHADOW_IN) + pixmap = clearlooks_style->radio_pixmap_active[state_type]; + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + pixmap = clearlooks_style->radio_pixmap_inconsistent[state_type]; + else + pixmap = clearlooks_style->radio_pixmap_nonactive[state_type]; + + x += (width - RADIO_SIZE)/2; + y += (height - RADIO_SIZE)/2; + +#ifndef GTKOSX + gdk_gc_set_clip_mask (gc, clearlooks_style->radio_pixmap_mask); + gdk_gc_set_clip_origin (gc, x, y); +#endif + + gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, + RADIO_SIZE, RADIO_SIZE); + +#ifndef GTKOSX + gdk_gc_set_clip_origin (gc, 0, 0); + gdk_gc_set_clip_mask (gc, NULL); +#endif + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +/**************************************************************************/ + +static void +draw_shadow_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + /* I need to improve this function. */ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + GdkRegion *area_region = NULL, + *gap_region = NULL; + +#if DEBUG + printf("draw_shadow_gap: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + cl_rectangle_reset (&r, style); + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + if (area) + { + area_region = gdk_region_rectangle (area); + + switch (gap_side) + { + case GTK_POS_TOP: + { + GdkRectangle rect = { x+gap_x, y, gap_width, 2 }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_BOTTOM: + { + GdkRectangle rect = { x+gap_x, y+height-2, gap_width, 2 }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_LEFT: + { + GdkRectangle rect = { x, y+gap_x, 2, gap_width }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_RIGHT: + { + GdkRectangle rect = { x+width-2, y+gap_x, 2, gap_width }; + gap_region = gdk_region_rectangle (&rect); + break; + } + } + + gdk_region_subtract (area_region, gap_region); + } + + if (shadow_type == GTK_SHADOW_ETCHED_IN || + shadow_type == GTK_SHADOW_ETCHED_OUT) + { + GdkGC *a; + GdkGC *b; + + if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + a = style->light_gc[state_type]; + b = clearlooks_style->shade_gc[3]; + } + else + { + a = clearlooks_style->shade_gc[3]; + b = style->light_gc[state_type]; + } + + gdk_gc_set_clip_region (a, area_region); + gdk_gc_set_clip_region (b, area_region); + + r.bordergc = a; + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + + r.bordergc = b; + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + + gdk_gc_set_clip_region (a, NULL); + gdk_gc_set_clip_region (b, NULL); + } + else if (shadow_type == GTK_SHADOW_IN || shadow_type == GTK_SHADOW_OUT) + { + r.topleft = (shadow_type == GTK_SHADOW_OUT) ? style->light_gc[state_type] : clearlooks_style->shade_gc[1]; + r.bottomright = (shadow_type == GTK_SHADOW_OUT) ? clearlooks_style->shade_gc[1] : style->light_gc[state_type]; + r.bordergc = clearlooks_style->shade_gc[5]; + + gdk_gc_set_clip_region (r.bordergc, area_region); + gdk_gc_set_clip_region (r.topleft, area_region); + gdk_gc_set_clip_region (r.bottomright, area_region); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + gdk_gc_set_clip_region (r.bordergc, NULL); + gdk_gc_set_clip_region (r.topleft, NULL); + gdk_gc_set_clip_region (r.bottomright, NULL); + } + + if (area_region) + gdk_region_destroy (area_region); +} + +/**************************************************************************/ +static void +draw_hline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x1, + gint x2, + gint y) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + +#if DEBUG + printf("draw_hline\n"); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area); + + if (detail && !strcmp (detail, "label")) + { + if (state_type == GTK_STATE_INSENSITIVE) + gdk_draw_line (window, style->light_gc[state_type], x1 + 1, y + 1, x2 + 1, y + 1); + + gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y); + } + else + { + gdk_draw_line (window, clearlooks_style->shade_gc[2], x1, y, x2, y); + + /* if (DETAIL ("menuitem")) */ + gdk_draw_line (window, clearlooks_style->shade_gc[0], x1, y+1, x2, y+1); + } + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL); +} + +/**************************************************************************/ +static void +draw_vline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint y1, + gint y2, + gint x) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint thickness_light; + gint thickness_dark; + +#if DEBUG + printf("draw_vline\n"); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + thickness_light = style->xthickness / 2; + thickness_dark = style->xthickness - thickness_light; + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area); + + gdk_draw_line (window, clearlooks_style->shade_gc[2], x, y1, x, y2 - 1); + gdk_draw_line (window, clearlooks_style->shade_gc[0], x+1, y1, x+1, y2 - 1); + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL); +} + +/**************************************************************************/ +static void +draw_focus (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkPoint points[5]; + GdkGC *gc; + gboolean free_dash_list = FALSE; + gint line_width = 1; + gchar *dash_list = "\1\1"; + gint dash_len; + +#if DEBUG + printf("draw_focus: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + gc = clearlooks_style->shade_gc[6]; + + if (widget) + { + gtk_widget_style_get (widget, + "focus-line-width", &line_width, + "focus-line-pattern", (gchar *)&dash_list, + NULL); + + free_dash_list = TRUE; + } + + sanitize_size (window, &width, &height); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + gdk_gc_set_line_attributes (gc, line_width, + dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_MITER); + + + if (detail && !strcmp (detail, "add-mode")) + { + if (free_dash_list) + g_free (dash_list); + + dash_list = "\4\4"; + free_dash_list = FALSE; + } + + points[0].x = x + line_width / 2; + points[0].y = y + line_width / 2; + points[1].x = x + width - line_width + line_width / 2; + points[1].y = y + line_width / 2; + points[2].x = x + width - line_width + line_width / 2; + points[2].y = y + height - line_width + line_width / 2; + points[3].x = x + line_width / 2; + points[3].y = y + height - line_width + line_width / 2; + points[4] = points[0]; + + if (!dash_list[0]) + { + gdk_draw_lines (window, gc, points, 5); + } + else + { + dash_len = strlen (dash_list); + + if (dash_list[0]) + gdk_gc_set_dashes (gc, 0, dash_list, dash_len); + + gdk_draw_lines (window, gc, points, 3); + + points[2].x += 1; + + if (dash_list[0]) + { + gint dash_pixels = 0; + gint i; + + /* Adjust the dash offset for the bottom and left so we + * match up at the upper left. + */ + for (i = 0; i < dash_len; i++) + dash_pixels += dash_list[i]; + + if (dash_len % 2 == 1) + dash_pixels *= 2; + + gdk_gc_set_dashes (gc, + dash_pixels - (width + height - 2 * line_width) % dash_pixels, + dash_list, dash_len); + } + + gdk_draw_lines (window, gc, points + 2, 3); + } + + gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); + + if (free_dash_list) + g_free (dash_list); +} + +static void +draw_layout(GtkStyle * style, + GdkWindow * window, + GtkStateType state_type, + gboolean use_text, + GdkRectangle * area, + GtkWidget * widget, + const gchar * detail, gint x, gint y, PangoLayout * layout) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + g_return_if_fail(GTK_IS_STYLE (style)); + g_return_if_fail(window != NULL); + + parent_class->draw_layout(style, window, state_type, use_text, + area, widget, detail, x, y, layout); + + +} + +/**************************************************************************/ +static void +draw_resize_grip (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GdkWindowEdge edge, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + if (area) + { + gdk_gc_set_clip_rectangle (style->light_gc[state_type], area); + gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + } + + switch (edge) + { + case GDK_WINDOW_EDGE_NORTH_WEST: + /* make it square */ + if (width < height) + { + height = width; + } + else if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_NORTH: + if (width < height) + { + height = width; + } + break; + case GDK_WINDOW_EDGE_NORTH_EAST: + /* make it square, aligning to top right */ + if (width < height) + { + height = width; + } + else if (height < width) + { + x += (width - height); + width = height; + } + break; + case GDK_WINDOW_EDGE_WEST: + if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_EAST: + /* aligning to right */ + if (height < width) + { + x += (width - height); + width = height; + } + break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + /* make it square, aligning to bottom left */ + if (width < height) + { + y += (height - width); + height = width; + } + else if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_SOUTH: + /* align to bottom */ + if (width < height) + { + y += (height - width); + height = width; + } + break; + case GDK_WINDOW_EDGE_SOUTH_EAST: + /* make it square, aligning to bottom right */ + if (width < height) + { + y += (height - width); + height = width; + } + else if (height < width) + { + x += (width - height); + width = height; + } + break; + default: + g_assert_not_reached (); + } + + /* Clear background */ + gtk_style_apply_default_background (style, window, FALSE, + state_type, area, + x, y, width, height); + + switch (edge) + { + case GDK_WINDOW_EDGE_WEST: + case GDK_WINDOW_EDGE_EAST: + { + gint xi; + + xi = x; + + while (xi < x + width) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + xi, y + height); + + xi++; + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + xi, y + height); + + xi += 2; + } + } + break; + case GDK_WINDOW_EDGE_NORTH: + case GDK_WINDOW_EDGE_SOUTH: + { + gint yi; + + yi = y; + + while (yi < y + height) + { + gdk_draw_line (window, + style->light_gc[state_type], + x, yi, + x + width, yi); + + yi++; + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + x, yi, + x + width, yi); + + yi+= 2; + } + } + break; + case GDK_WINDOW_EDGE_NORTH_WEST: + { + gint xi, yi; + + xi = x + width; + yi = y + height; + + while (xi > x + 3) + { + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + x, yi); + + --xi; + --yi; + + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + x, yi); + + xi -= 3; + yi -= 3; + + } + } + break; + case GDK_WINDOW_EDGE_NORTH_EAST: + { + gint xi, yi; + + xi = x; + yi = y + height; + + while (xi < (x + width - 3)) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + x + width, yi); + + ++xi; + --yi; + + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + x + width, yi); + + xi += 3; + yi -= 3; + } + } + break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + { + gint xi, yi; + + xi = x + width; + yi = y; + + while (xi > x + 3) + { + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + x, yi, + xi, y + height); + + --xi; + ++yi; + + gdk_draw_line (window, + style->light_gc[state_type], + x, yi, + xi, y + height); + + xi -= 3; + yi += 3; + + } + } + break; + + case GDK_WINDOW_EDGE_SOUTH_EAST: + { + gint xi, yi; + + xi = x; + yi = y; + + while (xi < (x + width - 3)) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y + height, + x + width, yi); + + ++xi; + ++yi; + + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y + height, + x + width, yi); + + xi += 3; + yi += 3; + } + } + break; + default: + g_assert_not_reached (); + break; + } + + if (area) + { + gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } +} + +/**************************************************************************/ + +static void +clearlooks_style_init_from_rc (GtkStyle * style, + GtkRcStyle * rc_style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkColor *spot_color; + double shades[] = {1.065, 0.93, 0.896, 0.85, 0.768, 0.665, 0.4, 0.205}; + int i; + double contrast; + + parent_class->init_from_rc (style, rc_style); + + contrast = CLEARLOOKS_RC_STYLE (rc_style)->contrast; + + clearlooks_style->sunkenmenubar = CLEARLOOKS_RC_STYLE (rc_style)->sunkenmenubar; + clearlooks_style->progressbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->progressbarstyle; + clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle; + clearlooks_style->menuitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->menuitemstyle; + clearlooks_style->listviewitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->listviewitemstyle; + + /* Lighter to darker */ + for (i = 0; i < 8; i++) + { + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->shade[i], + (shades[i]-0.7) * contrast + 0.7); + } + + spot_color = clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (rc_style)); + + clearlooks_style->spot_color = *spot_color; + shade (&clearlooks_style->spot_color, &clearlooks_style->spot1, 1.42); + shade (&clearlooks_style->spot_color, &clearlooks_style->spot2, 1.05); + shade (&clearlooks_style->spot_color, &clearlooks_style->spot3, 0.65); + + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_UPPER], 0.5); + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_LOWER], 0.62); + shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_UPPER_ACTIVE], 0.5); + shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_LOWER_ACTIVE], 0.55); +} + +static GdkGC * +realize_color (GtkStyle * style, + GdkColor * color) +{ + GdkGCValues gc_values; + + gdk_colormap_alloc_color (style->colormap, color, FALSE, TRUE); + + gc_values.foreground = *color; + + return gtk_gc_get (style->depth, style->colormap, &gc_values, GDK_GC_FOREGROUND); +} + +static void +clearlooks_style_realize (GtkStyle * style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int i; + + parent_class->realize (style); + + for (i = 0; i < 8; i++) + clearlooks_style->shade_gc[i] = realize_color (style, &clearlooks_style->shade[i]); + + for (i=0; i < CL_BORDER_COUNT; i++) + clearlooks_style->border_gc[i] = realize_color (style, &clearlooks_style->border[i]); + + clearlooks_style->spot1_gc = realize_color (style, &clearlooks_style->spot1); + clearlooks_style->spot2_gc = realize_color (style, &clearlooks_style->spot2); + clearlooks_style->spot3_gc = realize_color (style, &clearlooks_style->spot3); + + /* set light inset color */ + for (i=0; i<5; i++) + { + shade (&style->bg[i], &clearlooks_style->inset_dark[i], 0.93); + gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_dark[i]); + + shade (&style->bg[i], &clearlooks_style->inset_light[i], 1.055); + gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_light[i]); + + shade (&style->bg[i], &clearlooks_style->listview_bg[i], 1.015); + gdk_rgb_find_color (style->colormap, &clearlooks_style->listview_bg[i]); + + /* CREATE GRADIENT FOR BUTTONS */ + shade (&style->bg[i], &clearlooks_style->button_g1[i], 1.055); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g1[i]); + + shade (&style->bg[i], &clearlooks_style->button_g2[i], 1.005); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g2[i]); + + shade (&style->bg[i], &clearlooks_style->button_g3[i], 0.98); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g3[i]); + + shade (&style->bg[i], &clearlooks_style->button_g4[i], 0.91); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g4[i]); + } + +} + +static void +clearlooks_style_unrealize (GtkStyle * style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int i; + + /* We don't free the colors, because we don't know if + * gtk_gc_release() actually freed the GC. FIXME - need + * a way of ref'ing colors explicitely so GtkGC can + * handle things properly. + */ + for (i=0; i < 8; i++) + gtk_gc_release (clearlooks_style->shade_gc[i]); + + gtk_gc_release (clearlooks_style->spot1_gc); + gtk_gc_release (clearlooks_style->spot2_gc); + gtk_gc_release (clearlooks_style->spot3_gc); + + for (i = 0; i < 5; i++) + { + if (clearlooks_style->radio_pixmap_nonactive[i] != NULL) + { + g_object_unref (clearlooks_style->radio_pixmap_nonactive[i]); + clearlooks_style->radio_pixmap_nonactive[i] = NULL; + g_object_unref (clearlooks_style->radio_pixmap_active[i]); + clearlooks_style->radio_pixmap_active[i] = NULL; + g_object_unref (clearlooks_style->radio_pixmap_inconsistent[i]); + clearlooks_style->radio_pixmap_inconsistent[i] = NULL; + } + + if (clearlooks_style->check_pixmap_nonactive[i] != NULL) + { + g_object_unref (clearlooks_style->check_pixmap_nonactive[i]); + clearlooks_style->check_pixmap_nonactive[i] = NULL; + g_object_unref (clearlooks_style->check_pixmap_active[i]); + clearlooks_style->check_pixmap_active[i] = NULL; + g_object_unref (clearlooks_style->check_pixmap_inconsistent[i]); + clearlooks_style->check_pixmap_inconsistent[i] = NULL; + } + } + + if (clearlooks_style->radio_pixmap_mask != NULL) + g_object_unref (clearlooks_style->radio_pixmap_mask); + + clearlooks_style->radio_pixmap_mask = NULL; + + while (progressbars = g_list_first (progressbars)) + cl_progressbar_remove (progressbars->data); + + if (timer_id != 0) + { + g_source_remove(timer_id); + timer_id = 0; + } + + parent_class->unrealize (style); +} + +static GdkPixbuf * +set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent) +{ + GdkPixbuf *target; + guchar *data, *current; + guint x, y, rowstride, height, width; + + g_return_val_if_fail (pixbuf != NULL, NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + /* Returns a copy of pixbuf with it's non-completely-transparent pixels to + have an alpha level "alpha_percent" of their original value. */ + + target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + + if (alpha_percent == 1.0) + return target; + width = gdk_pixbuf_get_width (target); + height = gdk_pixbuf_get_height (target); + rowstride = gdk_pixbuf_get_rowstride (target); + data = gdk_pixbuf_get_pixels (target); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + /* The "4" is the number of chars per pixel, in this case, RGBA, + the 3 means "skip to the alpha" */ + current = data + (y * rowstride) + (x * 4) + 3; + *(current) = (guchar) (*(current) * alpha_percent); + } + } + + return target; +} + +static GdkPixbuf* +scale_or_ref (GdkPixbuf *src, + int width, + int height) +{ + if (width == gdk_pixbuf_get_width (src) && + height == gdk_pixbuf_get_height (src)) { + return g_object_ref (src); + } else { + return gdk_pixbuf_scale_simple (src, + width, height, + GDK_INTERP_BILINEAR); + } +} + +static GdkPixbuf * +render_icon (GtkStyle *style, + const GtkIconSource *source, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail) +{ + int width = 1; + int height = 1; + GdkPixbuf *scaled; + GdkPixbuf *stated; + GdkPixbuf *base_pixbuf; + GdkScreen *screen; + GtkSettings *settings; + + /* Oddly, style can be NULL in this function, because + * GtkIconSet can be used without a style and if so + * it uses this function. + */ + + base_pixbuf = gtk_icon_source_get_pixbuf (source); + + g_return_val_if_fail (base_pixbuf != NULL, NULL); + + if (widget && gtk_widget_has_screen (widget)) { + screen = gtk_widget_get_screen (widget); + settings = gtk_settings_get_for_screen (screen); + } else if (style->colormap) { + screen = gdk_colormap_get_screen (style->colormap); + settings = gtk_settings_get_for_screen (screen); + } else { + settings = gtk_settings_get_default (); + GTK_NOTE (MULTIHEAD, + g_warning ("Using the default screen for gtk_default_render_icon()")); + } + + + if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) { + g_warning (G_STRLOC ": invalid icon size '%d'", size); + return NULL; + } + + /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise, + * leave it alone. + */ + if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source)) + scaled = scale_or_ref (base_pixbuf, width, height); + else + scaled = g_object_ref (base_pixbuf); + + /* If the state was wildcarded, then generate a state. */ + if (gtk_icon_source_get_state_wildcarded (source)) { + if (state == GTK_STATE_INSENSITIVE) { + stated = set_transparency (scaled, 0.3); +#if 0 + stated = + gdk_pixbuf_composite_color_simple (scaled, + gdk_pixbuf_get_width (scaled), + gdk_pixbuf_get_height (scaled), + GDK_INTERP_BILINEAR, 128, + gdk_pixbuf_get_width (scaled), + style->bg[state].pixel, + style->bg[state].pixel); +#endif + gdk_pixbuf_saturate_and_pixelate (stated, stated, + 0.1, FALSE); + + g_object_unref (scaled); + } else if (state == GTK_STATE_PRELIGHT) { + stated = gdk_pixbuf_copy (scaled); + + gdk_pixbuf_saturate_and_pixelate (scaled, stated, + 1.2, FALSE); + + g_object_unref (scaled); + } else { + stated = scaled; + } + } + else + stated = scaled; + + return stated; +} + +static void +clearlooks_style_init (ClearlooksStyle * style) +{ +} + +static void +clearlooks_style_class_init (ClearlooksStyleClass * klass) +{ + GtkStyleClass *style_class = GTK_STYLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + style_class->realize = clearlooks_style_realize; + style_class->unrealize = clearlooks_style_unrealize; + style_class->init_from_rc = clearlooks_style_init_from_rc; + style_class->draw_focus = draw_focus; + style_class->draw_resize_grip = draw_resize_grip; + style_class->draw_handle = draw_handle; + style_class->draw_vline = draw_vline; + style_class->draw_hline = draw_hline; + style_class->draw_slider = draw_slider; + style_class->draw_shadow_gap = draw_shadow_gap; + style_class->draw_arrow = clearlooks_draw_arrow; + style_class->draw_check = draw_check; + style_class->draw_tab = draw_tab; + style_class->draw_box = draw_box; + style_class->draw_shadow = draw_shadow; + style_class->draw_box_gap = draw_box_gap; + style_class->draw_extension = draw_extension; + style_class->draw_option = draw_option; + style_class->draw_layout = draw_layout; + style_class->render_icon = render_icon; + style_class->draw_flat_box = draw_flat_box; +} + +GType clearlooks_type_style = 0; + +void +clearlooks_style_register_type (GTypeModule * module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_style_init, + NULL + }; + + clearlooks_type_style = g_type_module_register_type (module, + GTK_TYPE_STYLE, + "ClearlooksStyle", + &object_info, 0); +} diff --git a/libs/clearlooks-older/clearlooks_style.h b/libs/clearlooks-older/clearlooks_style.h new file mode 100644 index 0000000000..1e07877bf7 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_style.h @@ -0,0 +1,108 @@ +/* Clearlooks Engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor + * and by Alexander Larsson + * Modified by Richard Stellingwerff + */ +#include + +#include "clearlooks_draw.h" + +typedef struct _ClearlooksStyle ClearlooksStyle; +typedef struct _ClearlooksStyleClass ClearlooksStyleClass; + +extern GType clearlooks_type_style; + +#define CLEARLOOKS_TYPE_STYLE clearlooks_type_style +#define CLEARLOOKS_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_STYLE, ClearlooksStyle)) +#define CLEARLOOKS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) +#define CLEARLOOKS_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) + +typedef enum +{ + CL_BORDER_UPPER = 0, + CL_BORDER_LOWER, + CL_BORDER_UPPER_ACTIVE, + CL_BORDER_LOWER_ACTIVE, + CL_BORDER_COUNT +} ClBorderColorType; + +typedef enum +{ + CL_SCROLLBUTTON_BEGIN = 0, + CL_SCROLLBUTTON_END, + CL_SCROLLBUTTON_OTHER +} ClScrollButtonType; + +struct _ClearlooksStyle +{ + GtkStyle parent_instance; + + GdkColor shade[9]; + + GdkColor spot_color; + GdkColor spot1; + GdkColor spot2; + GdkColor spot3; + + GdkColor border[CL_BORDER_COUNT]; + + /* from light to dark */ + GdkGC *shade_gc[9]; + GdkGC *border_gc[CL_BORDER_COUNT]; + + GdkGC *spot1_gc; + GdkGC *spot2_gc; + GdkGC *spot3_gc; + + GdkColor inset_light[5]; + GdkColor inset_dark[5]; + + GdkColor button_g1[5]; + GdkColor button_g2[5]; + GdkColor button_g3[5]; + GdkColor button_g4[5]; + + GdkColor listview_bg[5]; + + GdkPixmap *radio_pixmap_nonactive[5]; + GdkPixmap *radio_pixmap_active[5]; + GdkPixmap *radio_pixmap_inconsistent[5]; + GdkBitmap *radio_pixmap_mask; /* All masks are the same */ + + GdkPixmap *check_pixmap_nonactive[5]; + GdkPixmap *check_pixmap_active[5]; + GdkPixmap *check_pixmap_inconsistent[5]; + + gboolean sunkenmenubar:1; + + guint8 progressbarstyle; + guint8 menubarstyle; + guint8 menuitemstyle; + guint8 listviewitemstyle; +}; + +struct _ClearlooksStyleClass +{ + GtkStyleClass parent_class; +}; + +void clearlooks_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks-older/clearlooks_theme_main.c b/libs/clearlooks-older/clearlooks_theme_main.c new file mode 100644 index 0000000000..5356f915dd --- /dev/null +++ b/libs/clearlooks-older/clearlooks_theme_main.c @@ -0,0 +1,37 @@ +#include +#include + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +G_MODULE_EXPORT void +theme_init (GTypeModule *module) +{ + clearlooks_rc_style_register_type (module); + clearlooks_style_register_type (module); + printf("theme_init() called from internal clearlooks engine\n"); +} + +G_MODULE_EXPORT void +theme_exit (void) +{ +} + +G_MODULE_EXPORT GtkRcStyle * +theme_create_rc_style (void) +{ + return GTK_RC_STYLE (g_object_new (CLEARLOOKS_TYPE_RC_STYLE, NULL)); +} + +/* The following function will be called by GTK+ when the module + * is loaded and checks to see if we are compatible with the + * version of GTK+ that loads us. + */ +G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module); +const gchar* +g_module_check_init (GModule *module) +{ + return gtk_check_version (GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION - GTK_INTERFACE_AGE); +} diff --git a/libs/clearlooks-older/cpdll.sh b/libs/clearlooks-older/cpdll.sh new file mode 100755 index 0000000000..fb101d52a0 --- /dev/null +++ b/libs/clearlooks-older/cpdll.sh @@ -0,0 +1,2 @@ +mkdir engines +cp libclearlooks.so engines diff --git a/libs/clearlooks-older/support.c b/libs/clearlooks-older/support.c new file mode 100644 index 0000000000..358c7f43fb --- /dev/null +++ b/libs/clearlooks-older/support.c @@ -0,0 +1,981 @@ +#include "support.h" + +/* #define ALWAYS_DITHER_GRADIENTS */ + +GtkTextDirection +get_direction (GtkWidget *widget) +{ + GtkTextDirection dir; + + if (widget) + dir = gtk_widget_get_direction (widget); + else + dir = GTK_TEXT_DIR_LTR; + + return dir; +} + +GdkPixbuf * +generate_bit (unsigned char alpha[], GdkColor *color, double mult) +{ + guint r, g, b; + GdkPixbuf *pixbuf; + unsigned char *pixels; + int w, h, rs; + int x, y; + + r = (color->red >> 8) * mult; + r = MIN(r, 255); + g = (color->green >> 8) * mult; + g = MIN(g, 255); + b = (color->blue >> 8) * mult; + b = MIN(b, 255); + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, RADIO_SIZE, RADIO_SIZE); + + w = gdk_pixbuf_get_width (pixbuf); + h = gdk_pixbuf_get_height (pixbuf); + rs = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + + for (y=0; y < h; y++) + { + for (x=0; x < w; x++) + { + pixels[y*rs + x*4 + 0] = r; + pixels[y*rs + x*4 + 1] = g; + pixels[y*rs + x*4 + 2] = b; + if (alpha) + pixels[y*rs + x*4 + 3] = alpha[y*w + x]; + else + pixels[y*rs + x*4 + 3] = 255; + } + } + + return pixbuf; +} + +#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255))) + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color) +{ + GdkPixbuf *pixbuf; + double intensity; + int x, y; + const guchar *src, *asrc; + guchar *dest; + int dest_rowstride; + int width, height; + guchar *dest_pixels; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, RADIO_SIZE, RADIO_SIZE); + + if (pixbuf == NULL) + return NULL; + + dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + dest_pixels = gdk_pixbuf_get_pixels (pixbuf); + + for (y = 0; y < RADIO_SIZE; y++) + { + src = bit + y * RADIO_SIZE; + asrc = alpha + y * RADIO_SIZE; + dest = dest_pixels + y * dest_rowstride; + + for (x = 0; x < RADIO_SIZE; x++) + { + double dr, dg, db; + + intensity = (src[x] + 0 )/ 255.0; + + if (intensity <= 0.5) + { + /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */ + dr = (new_color->red * intensity * 2.0) / 65535.0; + dg = (new_color->green * intensity * 2.0) / 65535.0; + db = (new_color->blue * intensity * 2.0) / 65535.0; + } + else + { + /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */ + dr = (new_color->red + (65535 - new_color->red) * (intensity - 0.5) * 2.0) / 65535.0; + dg = (new_color->green + (65535 - new_color->green) * (intensity - 0.5) * 2.0) / 65535.0; + db = (new_color->blue + (65535 - new_color->blue) * (intensity - 0.5) * 2.0) / 65535.0; + } + + dest[0] = CLAMP_UCHAR (255 * dr); + dest[1] = CLAMP_UCHAR (255 * dg); + dest[2] = CLAMP_UCHAR (255 * db); + + dest[3] = asrc[x]; + dest += 4; + } + } + + return pixbuf; +} + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen) +{ + GdkGC *tmp_gc; + GdkPixmap *pixmap; + + pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + style->depth); + + gdk_drawable_set_colormap (pixmap, style->colormap); + + tmp_gc = gdk_gc_new (pixmap); + + gdk_pixbuf_render_to_drawable (pixbuf, pixmap, tmp_gc, 0, 0, 0, 0, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + + gdk_gc_unref (tmp_gc); + + return pixmap; +} + + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b) +{ + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + + l = (max + min) / 2; + s = 0; + h = 0; + + if (max != min) + { + if (l <= 0.5) + s = (max - min) / (max + min); + else + s = (max - min) / (2 - max - min); + + delta = max -min; + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h *= 60; + if (h < 0.0) + h += 360; + } + + *r = h; + *g = l; + *b = s; +} + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s) +{ + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + + if (lightness <= 0.5) + m2 = lightness * (1 + saturation); + else + m2 = lightness + saturation - lightness * saturation; + + m1 = 2 * lightness - m2; + + if (saturation == 0) + { + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h + 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + r = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1 + (m2 - m1) * (240 - hue) / 60; + else + r = m1; + + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + g = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1 + (m2 - m1) * (240 - hue) / 60; + else + g = m1; + + hue = *h - 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + b = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1 + (m2 - m1) * (240 - hue) / 60; + else + b = m1; + + *h = r; + *l = g; + *s = b; + } +} + +void +shade (GdkColor * a, GdkColor * b, float k) +{ + gdouble red; + gdouble green; + gdouble blue; + + red = (gdouble) a->red / 65535.0; + green = (gdouble) a->green / 65535.0; + blue = (gdouble) a->blue / 65535.0; + + rgb_to_hls (&red, &green, &blue); + + green *= k; + if (green > 1.0) + green = 1.0; + else if (green < 0.0) + green = 0.0; + + blue *= k; + if (blue > 1.0) + blue = 1.0; + else if (blue < 0.0) + blue = 0.0; + + hls_to_rgb (&red, &green, &blue); + + b->red = red * 65535.0; + b->green = green * 65535.0; + b->blue = blue * 65535.0; +} + + +/**************************************************************************/ + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last) +{ + if (x2 - x1 < 7 && !last) /* 7 to get garretts pixels, otherwise 6 */ + { + gdk_draw_line (window, gc, x1, y, x2, y); + } + else if (last) + { + /* we don't draw "spikes" for very small arrows */ + if (x2 - x1 <= 9) + { + /*gdk_draw_line (window, gc, x1+1, y, x1+1, y); + gdk_draw_line (window, gc, x2-1, y, x2-1, y);*/ + } + else + { + gdk_draw_line (window, gc, x1+2, y, x1+2, y); + gdk_draw_line (window, gc, x2-2, y, x2-2, y); + } + } + else + { + gdk_draw_line (window, gc, x1, y, x1+2, y); + gdk_draw_line (window, gc, x2-2, y, x2, y); + } +} + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last) +{ + if (y2 - y1 < 7 && !last) /* 7 to get garretts pixels */ + gdk_draw_line (window, gc, x, y1, x, y2); + else if (last) + { + /* we don't draw "spikes" for very small arrows */ + if (y2 - y1 > 9) { + gdk_draw_line (window, gc, x, y1+2, x, y1+2); + gdk_draw_line (window, gc, x, y2-2, x, y2-2); + } + } + else + { + gdk_draw_line (window, gc, x, y1, x, y1+2); + gdk_draw_line (window, gc, x, y2-2, x, y2); + } +} + + + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height) +{ + gint i, j; + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (arrow_type == GTK_ARROW_DOWN) + { + for (i = 0, j = -1; i < height; i++, j++) + arrow_draw_hline (window, gc, x + j, x + width - j - 1, y + i, i == 0); + + } + else if (arrow_type == GTK_ARROW_UP) + { + for (i = height - 1, j = -1; i >= 0; i--, j++) + arrow_draw_hline (window, gc, x + j, x + width - j - 1, y + i, i == height - 1); + } + else if (arrow_type == GTK_ARROW_LEFT) + { + for (i = width - 1, j = -1; i >= 0; i--, j++) + arrow_draw_vline (window, gc, y + j, y + height - j - 1, x + i, i == width - 1); + } + else if (arrow_type == GTK_ARROW_RIGHT) + { + for (i = 0, j = -1; i < width; i++, j++) + arrow_draw_vline (window, gc, y + j, y + height - j - 1, x + i, i == 0); + } + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height) +{ + gint w = *width; + gint h = *height; + + switch (arrow_type) + { + case GTK_ARROW_UP: + case GTK_ARROW_DOWN: + w += (w % 2) - 1; + h = (w / 2 + 1) + 1; + + if (h > *height) + { + h = *height; + w = 2 * (h - 1) - 1; + } + + if (arrow_type == GTK_ARROW_DOWN) + { + if (*height % 2 == 1 || h % 2 == 0) + *height += 1; + } + else + { + if (*height % 2 == 0 || h % 2 == 0) + *height -= 1; + } + break; + + case GTK_ARROW_RIGHT: + case GTK_ARROW_LEFT: + h += (h % 2) - 1; + w = (h / 2 + 1) + 1; + + if (w > *width) + { + w = *width; + h = 2 * (w - 1) - 1; + } + + if (arrow_type == GTK_ARROW_RIGHT) + { + if (*width % 2 == 1 || w % 2 == 0) + *width += 1; + } + else + { + if (*width % 2 == 0 || w % 2 == 0) + *width -= 1; + } + break; + + default: + /* should not be reached */ + break; + } + + *x += (*width - w) / 2; + *y += (*height - h) / 2; + *height = h; + *width = w; +} + + +void gtk_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header, + gint *column_index, gint *columns, +gboolean *resizable) +{ + GList *list; + *column_index = *columns = 0; + list = gtk_tree_view_get_columns (tv); + + do + { + GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data); + if ( column->button == header ) + { + *column_index = *columns; + *resizable = column->resizable; + } + if ( column->visible ) + (*columns)++; + } while ((list = g_list_next(list))); +} + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns) +{ + *columns = clist->columns; + int i; + + for (i=0; i<*columns; i++) + { + if (clist->column[i].button == button) + { + *column_index = i; + break; + } + } +} + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height) +{ + gboolean set_bg = FALSE; + + if ((*width == -1) && (*height == -1)) + { + set_bg = GDK_IS_WINDOW (window); + gdk_window_get_size (window, width, height); + } + else if (*width == -1) + gdk_window_get_size (window, width, NULL); + else if (*height == -1) + gdk_window_get_size (window, NULL, height); + + return set_bg; +} + +static GtkRequisition default_option_indicator_size = { 7, 13 }; +static GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 }; + +void +option_menu_get_props (GtkWidget *widget, + GtkRequisition *indicator_size, + GtkBorder *indicator_spacing) +{ + GtkRequisition *tmp_size = NULL; + GtkBorder *tmp_spacing = NULL; + + if (widget) + gtk_widget_style_get (widget, "indicator_size", &tmp_size, + "indicator_spacing", &tmp_spacing, NULL); + + if (tmp_size) + { + *indicator_size = *tmp_size; + g_free (tmp_size); + } + else + *indicator_size = default_option_indicator_size; + + if (tmp_spacing) + { + *indicator_spacing = *tmp_spacing; + g_free (tmp_spacing); + } + else + *indicator_spacing = default_option_indicator_spacing; +} + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type) +{ + g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL); + + while (widget && widget->parent + && !g_type_is_a(GTK_WIDGET_TYPE(widget->parent), + widget_type)) + widget = widget->parent; + + if (! + (widget && widget->parent + && g_type_is_a(GTK_WIDGET_TYPE(widget->parent), widget_type))) + return NULL; + + return widget; +} + +/* Dithered Gradient Buffers */ +static void +internel_image_buffer_free_pixels (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +static GdkPixbuf* +internal_image_buffer_new (gint width, gint height) +{ + guchar *buf; + int rowstride; + + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + rowstride = width * 3; + + buf = g_try_malloc (height * rowstride); + + if (!buf) + return NULL; + + return gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB, + FALSE, 8, + width, height, rowstride, + internel_image_buffer_free_pixels, NULL); +} + +static void +internal_color_get_as_uchars(GdkColor *color, + guchar *red, + guchar *green, + guchar *blue) +{ + *red = (guchar) (color->red / 256.0); + *green = (guchar) (color->green / 256.0); + *blue = (guchar) (color->blue / 256.0); +} + +static GdkPixbuf* +internal_create_horizontal_gradient_image_buffer (gint width, gint height, + GdkColor *from, + GdkColor *to) +{ + int i; + long r, g, b, dr, dg, db; + GdkPixbuf* buffer; + guchar *ptr; + guchar *pixels; + guchar r0, g0, b0; + guchar rf, gf, bf; + int rowstride; + + buffer = internal_image_buffer_new (width, height); + + if (buffer == NULL) + return NULL; + + pixels = gdk_pixbuf_get_pixels (buffer); + ptr = pixels; + rowstride = gdk_pixbuf_get_rowstride (buffer); + + internal_color_get_as_uchars(from, &r0, &g0, &b0); + internal_color_get_as_uchars(to, &rf, &gf, &bf); + + r = r0 << 16; + g = g0 << 16; + b = b0 << 16; + + dr = ((rf-r0)<<16)/width; + dg = ((gf-g0)<<16)/width; + db = ((bf-b0)<<16)/width; + + /* render the first line */ + for (i=0; i>16); + *(ptr++) = (guchar)(g>>16); + *(ptr++) = (guchar)(b>>16); + + r += dr; + g += dg; + b += db; + } + + /* copy the first line to the other lines */ + for (i=1; i>16; + ptr[1] = g>>16; + ptr[2] = b>>16; + + if (width > 1) + { + last_block = 0; + + for (j=1; j <= max_block; j *= 2) + { + memcpy (&(ptr[j*3]), ptr, j*3); + + if ((j*2) >= max_block) + { + last_block = j*2; + } + } + + if ((last_block < width) && (last_block > 0)) + { + memcpy (&(ptr[last_block*3]), ptr, (width - last_block)*3); + } + } + + r += dr; + g += dg; + b += db; + } + + return buffer; +} + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color) +{ + #ifndef ALWAYS_DITHER_GRADIENTS + gboolean dither = ((style->depth > 0) && (style->depth <= 16)); + #endif + + if ((width <= 0) || (height <= 0)) + return; + + if ( left_color == NULL || right_color == NULL ) + { + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + return; + } + + #ifndef ALWAYS_DITHER_GRADIENTS + if (dither) + #endif + { + GdkPixbuf *image_buffer = NULL; + + image_buffer = internal_create_horizontal_gradient_image_buffer (width, height, left_color, right_color); + + if (image_buffer) + { + gdk_draw_pixbuf(drawable, gc, image_buffer, 0, 0, x, y, width, height, GDK_RGB_DITHER_MAX, 0, 0); + + g_object_unref(image_buffer); + } + } + #ifndef ALWAYS_DITHER_GRADIENTS + else + { + int i; + GdkColor col; + int dr, dg, db; + GdkGCValues old_values; + + gdk_gc_get_values (gc, &old_values); + + if (left_color == right_color ) + { + col = *left_color; + gdk_rgb_find_color (style->colormap, &col); + gdk_gc_set_foreground (gc, &col); + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + gdk_gc_set_foreground (gc, &old_values.foreground); + return; + } + + col = *left_color; + dr = (right_color->red - left_color->red) / width; + dg = (right_color->green - left_color->green) / width; + db = (right_color->blue - left_color->blue) / width; + + for (i = 0; i < width; i++) + { + gdk_rgb_find_color (style->colormap, &col); + + gdk_gc_set_foreground (gc, &col); + gdk_draw_line (drawable, gc, x + i, y, x + i, y + height - 1); + + col.red += dr; + col.green += dg; + col.blue += db; + } + + gdk_gc_set_foreground (gc, &old_values.foreground); + } + #endif +} + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color) +{ + #ifndef ALWAYS_DITHER_GRADIENTS + gboolean dither = ((style->depth > 0) && (style->depth <= 16)); + #endif + + if ((width <= 0) || (height <= 0)) + return; + + #ifndef ALWAYS_DITHER_GRADIENTS + if (dither) + #endif + { + GdkPixbuf *image_buffer = NULL; + + image_buffer = internal_create_vertical_gradient_image_buffer (width, height, top_color, bottom_color); + + if (image_buffer) + { + gdk_draw_pixbuf(drawable, gc, image_buffer, 0, 0, x, y, width, height, GDK_RGB_DITHER_MAX, 0, 0); + + g_object_unref(image_buffer); + } + } + #ifndef ALWAYS_DITHER_GRADIENTS + else + { + int i; + GdkColor col; + int dr, dg, db; + GdkGCValues old_values; + + gdk_gc_get_values (gc, &old_values); + + if (top_color == bottom_color ) + { + col = *top_color; + gdk_rgb_find_color (style->colormap, &col); + gdk_gc_set_foreground (gc, &col); + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + gdk_gc_set_foreground (gc, &old_values.foreground); + return; + } + + col = *top_color; + dr = (bottom_color->red - top_color->red) / height; + dg = (bottom_color->green - top_color->green) / height; + db = (bottom_color->blue - top_color->blue) / height; + + for (i = 0; i < height; i++) + { + gdk_rgb_find_color (style->colormap, &col); + + gdk_gc_set_foreground (gc, &col); + gdk_draw_line (drawable, gc, x, y + i, x + width - 1, y + i); + + col.red += dr; + col.green += dg; + col.blue += db; + } + + gdk_gc_set_foreground (gc, &old_values.foreground); + } + #endif +} + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha) +{ + int inAlpha = 100-alpha; + c->red = (a->red * alpha + b->red * inAlpha) / 100; + c->green = (a->green * alpha + b->green * inAlpha) / 100; + c->blue = (a->blue * alpha + b->blue * inAlpha) / 100; + + gdk_rgb_find_color (colormap, c); +} + +GtkWidget *get_parent_window (GtkWidget *widget) +{ + GtkWidget *parent = widget->parent; + + while (parent && GTK_WIDGET_NO_WINDOW (parent)) + parent = parent->parent; + + return parent; +} + +GdkColor *get_parent_bgcolor (GtkWidget *widget) +{ + GtkWidget *parent = get_parent_window (widget); + + if (parent && parent->style) + return &parent->style->bg[GTK_STATE_NORMAL]; + + return NULL; +} + +GtkWidget * +find_combo_box_widget (GtkWidget * widget) +{ + GtkWidget *result = NULL; + + if (widget && !GTK_IS_COMBO_BOX_ENTRY (widget)) + { + if (GTK_IS_COMBO_BOX (widget)) + result = widget; + else + result = find_combo_box_widget(widget->parent); + } + + return result; +} + +gboolean +is_combo_box (GtkWidget * widget) +{ + return (find_combo_box_widget(widget) != NULL); +} diff --git a/libs/clearlooks-older/support.h b/libs/clearlooks-older/support.h new file mode 100644 index 0000000000..a1430b40d0 --- /dev/null +++ b/libs/clearlooks-older/support.h @@ -0,0 +1,110 @@ +#include +#include +#include + +/* GTK 2.2 compatibility */ +#ifndef GTK_IS_COMBO_BOX_ENTRY + #define GTK_IS_COMBO_BOX_ENTRY(x) 0 +#endif +#ifndef GTK_IS_COMBO_BOX + #define GTK_IS_COMBO_BOX(x) 0 +#endif + +#define RADIO_SIZE 13 +#define CHECK_SIZE 13 + +GtkTextDirection +get_direction (GtkWidget *widget); + +GdkPixbuf * +generate_bit (unsigned char alpha[], + GdkColor *color, + double mult); + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color); + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen); + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height); + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b); + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s); + +void +shade (GdkColor * a, GdkColor * b, float k); + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color); + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color); + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last); + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last); + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height); + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height); + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type); + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha); + +GtkWidget *get_parent_window (GtkWidget *widget); + +GdkColor *get_parent_bgcolor (GtkWidget *widget); + +gboolean is_combo_box (GtkWidget * widget); + +GtkWidget *find_combo_box_widget (GtkWidget * widget); + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns); -- cgit v1.2.3